第一件事是正确地获得名字:>>> def increment(obj):
... obj.count += 1
...
>>> class A(object):
... def __init__(self):
... self.count = 0
...
>>> o = A()
>>> o.__init__
>
>>> increment
所以专有名称是函数和绑定方法。现在你可以看看如何Bind an Unbound Method,你可能会读到关于descriptors:In general, a descriptor is an object attribute with "binding
behavior", one whose attribute access has been overridden by methods
in the descriptor protocol. Those methods are __get__, __set__, and
__delete__. If any of those methods are defined for an object, it is said to be a descriptor.
只需使用__get__的不同调用,就可以轻松地将函数转换为方法
^{pr2}$
它就像一种魅力:>>> o = A()
>>> increment.__get__(None, type(None))(o)
>>> o.count
1
>>> increment.__get__(o, type(o))()
>>> o.count
2
您可以轻松地将这些新绑定方法添加到对象:def increment(obj):
obj.count += 1
def addition(obj, number):
obj.count += number
class A(object):
def __init__(self):
self.count = 0
o = A()
o.inc = increment.__get__(o)
o.add = addition.__get__(o)
print(o.count) # 0
o.inc()
print(o.count) # 1
o.add(5)
print(o.count) # 6
或者创建自己的描述符,将函数转换为绑定方法:class BoundMethod(object):
def __init__(self, function):
self.function = function
def __get__(self, obj, objtype=None):
print('Getting', obj, objtype)
return self.function.__get__(obj, objtype)
class B(object):
def __init__(self):
self.count = 0
inc = BoundMethod(increment)
add = BoundMethod(addition)
o = B()
print(o.count) # 0
o.inc()
# Getting <__main__.B object at 0x0000000002677978>
print(o.count) # 1
o.add(5)
# Getting <__main__.B object at 0x0000000002677978>
print(o.count) # 6Class dictionaries store methods as functions. In a class definition, methods are written using def and lambda, the usual tools for creating functions. The only difference from regular functions is that the first argument is reserved for the object instance. By Python convention, the instance reference is called self but may be called this or any other variable name.
To support method calls, functions include the __get__() method for binding methods during attribute access. This means that all functions are non-data descriptors which return bound or unbound methods depending whether they are invoked from an object or a class.
在实例初始化过程中,函数变成绑定方法:>>> B.add
# Getting None
>>> o.add
# Getting <__main__.B object at 0x00000000030B1128>
>