Extension methods in Python

后端 未结 6 967
没有蜡笔的小新
没有蜡笔的小新 2021-01-31 01:55

Does Python have extension methods like C#? Is it possible to call a method like:

MyRandomMethod()

on existing types like int?

相关标签:
6条回答
  • 2021-01-31 02:28

    not sure if that what you're asking but you can extend existing types and then call whatever you like on the new thing:

    class  int(int):
         def random_method(self):
               return 4                     # guaranteed to be random
    v = int(5)                              # you'll have to instantiate all you variables like this
    v.random_method()
    
    class int(int):
        def xkcd(self):
            import antigravity
            print(42)
    
    >>>v.xkcd()
    Traceback (most recent call last):
      File "<pyshell#81>", line 1, in <module>
        v.xkcd()
    AttributeError: 'int' object has no attribute 'xkcd'
    c = int(1)
    >>> c.random_method()
    4
    >>> c.xkcd()
    42
    

    hope that clarifies your question

    0 讨论(0)
  • 2021-01-31 02:28

    I've had great luck with the method described here:

    http://mail.python.org/pipermail/python-dev/2008-January/076194.html

    I have no idea if it works on builtins though.

    0 讨论(0)
  • 2021-01-31 02:36

    Another option is to override the meta-class. This allows you to, among other things, specify functions that should exist in all classes.

    This article starts to discuss it:

    http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html

    0 讨论(0)
  • 2021-01-31 02:43

    The following context manager adds the method like Forbidden Fruit would without the limitations of it. Besides that it has the additional benefit of removing the extension method afterwards:

    class extension_method:
    
        def __init__(self, obj, method):
            method_name = method.__name__
            setattr(obj, method_name, method)
            self.obj = obj
            self.method_name = method_name
    
        def __enter__(self):
            return self.obj
    
        def __exit__(self, type, value, traceback):
            # remove this if you want to keep the extension method after context exit
            delattr(self.obj, self.method_name)
    
    

    Usage is as follows:

    class C:
        pass
    
    def get_class_name(self):
        return self.__class__.__name__
    
    with extension_method(C, get_class_name):
        assert hasattr(C, 'get_class_name') # the method is added to C
        c = C()
        print(c.get_class_name()) # prints 'C'
    
    assert not hasattr(C, 'get_class_name') # the method is gone from C
    
    0 讨论(0)
  • 2021-01-31 02:47

    You can add whatever methods you like on class objects defined in Python code (AKA monkey patching):

    >>> class A(object):
    >>>     pass
    
    
    >>> def stuff(self):
    >>>     print self
    
    >>> A.test = stuff
    >>> A().test()
    

    This does not work on builtin types, because their __dict__ is not writable (it's a dictproxy).

    So no, there is no "real" extension method mechanism in Python.

    0 讨论(0)
  • 2021-01-31 02:49

    It can be done with Forbidden Fruit (https://pypi.python.org/pypi/forbiddenfruit)

    Install forbiddenfruit:

    pip install forbiddenfruit
    

    Then you can extend built-in types:

    >>> from forbiddenfruit import curse
    
    >>> def percent(self, delta):
    ...     return self * (1 + delta / 100)
    
    >>> curse(float, 'percent', percent)
    >>> 1.0.percent(5)
    1.05
    

    Forbidden Fruit is fundamentally dependent on the C API, it works only on cpython implementations and won’t work on other python implementations, such as Jython, pypy, etc.

    0 讨论(0)
提交回复
热议问题