python extension methods

主宰稳场 提交于 2019-12-03 00:00:05

You can just modify the class directly, sometimes known as monkey patching.

def MyMethod(self):
      return self + self

MyClass.MyMethod = MyMethod
del(MyMethod)#clean up namespace

I'm not 100% sure you can do this on a special class like str, but it's fine for your user-defined classes.

Update

You confirm in a comment my suspicion that this is not possible for a builtin like str. In which case I believe there is no analogue to C# extension methods for such classes.

Finally, the convenience of these methods, in both C# and Python, comes with an associated risk. Using these techniques can make code more complex to understand and maintain.

You can change the built-in classes by monkey-patching with the help of forbidden fruit

But installing forbidden fruit requires a C compiler and unrestricted environment so it probably will not work or needs hard effort to run on Google App Engine, Heroku, etc.

I changed the behaviour of unicode class in Python 2.7 for a Turkish i,I uppercase/lowercase problem by this library.

# -*- coding: utf8 -*-
# Redesigned by @guneysus

import __builtin__
from forbiddenfruit import curse

lcase_table = tuple(u'abcçdefgğhıijklmnoöprsştuüvyz')
ucase_table = tuple(u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ')


def upper(data):
    data = data.replace('i',u'İ')
    data = data.replace(u'ı',u'I')
    result = ''
    for char in data:
        try:
            char_index = lcase_table.index(char)
            ucase_char = ucase_table[char_index]
        except:
            ucase_char = char
        result += ucase_char
    return result

curse(__builtin__.unicode, 'upper', upper)
class unicode_tr(unicode):
    """For Backward compatibility"""
    def __init__(self, arg):
        super(unicode_tr, self).__init__(*args, **kwargs)

if __name__ == '__main__':
    print u'istanbul'.upper()

You can do what you have asked like the following:

def extension_method(self):
    #do stuff
class.extension_method = extension_method

C# implemented extension methods because it lacks first class functions, Python has them and it is the preferred method for "wrapping" common functionality across disparate classes in Python.

There are good reasons to believe Python will never have extension methods, simply look at the available built-ins:

len(o) calls o.__len__
iter(o) calls o.__iter__
next(o) calls o.next
format(o, s) calls o.__format__(s)

Basically, Python likes functions.

After a week, I have a solution that is closest to what I was seeking for. The solution consists of using getattr and __getattr__. Here is an example for those who are interested.

class myClass:

    def __init__(self): pass

    def __getattr__(self, attr): 
        try:
            methodToCall = getattr(myClass, attr)
            return methodToCall(myClass(), self)
        except:
            pass

    def firstChild(self, node):
        # bla bla bla
    def lastChild(self, node):
        # bla bla bla 

x = myClass()
div = x.getMYDiv()
y = div.firstChild.lastChild 

I haven't test this example, I just gave it to give an idea for who might be interested. Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!