Adding a Method to an Existing Object Instance

后端 未结 16 2993
夕颜
夕颜 2020-11-21 05:45

I\'ve read that it is possible to add a method to an existing object (i.e., not in the class definition) in Python.

I understand that it\'s not always good to do so

16条回答
  •  时光说笑
    2020-11-21 05:59

    In Python, there is a difference between functions and bound methods.

    >>> def foo():
    ...     print "foo"
    ...
    >>> class A:
    ...     def bar( self ):
    ...         print "bar"
    ...
    >>> a = A()
    >>> foo
    
    >>> a.bar
    >
    >>>
    

    Bound methods have been "bound" (how descriptive) to an instance, and that instance will be passed as the first argument whenever the method is called.

    Callables that are attributes of a class (as opposed to an instance) are still unbound, though, so you can modify the class definition whenever you want:

    >>> def fooFighters( self ):
    ...     print "fooFighters"
    ...
    >>> A.fooFighters = fooFighters
    >>> a2 = A()
    >>> a2.fooFighters
    >
    >>> a2.fooFighters()
    fooFighters
    

    Previously defined instances are updated as well (as long as they haven't overridden the attribute themselves):

    >>> a.fooFighters()
    fooFighters
    

    The problem comes when you want to attach a method to a single instance:

    >>> def barFighters( self ):
    ...     print "barFighters"
    ...
    >>> a.barFighters = barFighters
    >>> a.barFighters()
    Traceback (most recent call last):
      File "", line 1, in 
    TypeError: barFighters() takes exactly 1 argument (0 given)
    

    The function is not automatically bound when it's attached directly to an instance:

    >>> a.barFighters
    
    

    To bind it, we can use the MethodType function in the types module:

    >>> import types
    >>> a.barFighters = types.MethodType( barFighters, a )
    >>> a.barFighters
    >
    >>> a.barFighters()
    barFighters
    

    This time other instances of the class have not been affected:

    >>> a2.barFighters()
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: A instance has no attribute 'barFighters'
    

    More information can be found by reading about descriptors and metaclass programming.

提交回复
热议问题