Chr*_*son 2 python python-2.7 python-descriptors
以此代码为例:
class SomeClass():
def a_method(self):
pass
print(SomeClass.a_method is SomeClass.a_method) # Example 1: False
print(SomeClass.a_method == SomeClass.a_method) # Example 2: True
print(SomeClass().a_method is SomeClass().a_method) # Example 3: False
print(SomeClass().a_method == SomeClass().a_method) # Example 4: False
Run Code Online (Sandbox Code Playgroud)
Someclass.a_method是一种未绑定的方法.现在这些在Python中都不存在,所以请考虑这是一个无用的历史课.
Python每次引用时都会复制该方法吗?
是的,或多或少.这是通过描述符协议完成的.
>>> SomeClass.a_method # unbound method via attribute access
<unbound method SomeClass.a_method>
>>> SomeClass.__dict__['a_method'] # just stored as a function in the class dict
<function __main__.a_method>
>>> SomeClass.__dict__['a_method'].__get__(None, SomeClass)
<unbound method SomeClass.a_method>
Run Code Online (Sandbox Code Playgroud)
最后一行显示了描述符为类上的属性访问调用但是手动写出的"绑定"操作.在纯Python中,它就是这样的
class Function(object):
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
return types.MethodType(self, obj, objtype):
Run Code Online (Sandbox Code Playgroud)
您还可以通过以下方式创建绑定方法:
>>> some_instance = SomeClass()
>>> SomeClass.__dict__['a_method'].__get__(some_instance, SomeClass)
<bound method SomeClass.a_method of <__main__.SomeClass instance at 0xcafef00d>>
Run Code Online (Sandbox Code Playgroud)
方法比较通过方法的属性__func__和__self__属性完成.在这种情况下,它们都是相同的:__func__你可以从类字典中挖出相同的普通旧函数,而且__self__是None.因此,尽管这些方法是不同的对象,但它们相等.
正确.它们是不同的对象,因此不相同.
如前所述,比较是使用__func__和__self__属性.结果与示例2不匹配,因为在这种情况下,__self__属性引用不同的实例.那些不同的实例不比较相等,因为SomeClass实例按身份进行比较,因此方法也不比较相等.
除了示例1之外,上面提到的所有内容也适用于该语言的当前版本.在Python中,不再存在未绑定方法,删除了对象模型中的这种不必要的复杂性.
>>> SomeClass.a_method
<function __main__.SomeClass.a_method(self)>
>>> SomeClass.a_method is SomeClass.__dict__['a_method']
True
Run Code Online (Sandbox Code Playgroud)
Python 2中的"未绑定方法"现在只是一个普通的旧函数,通过属性访问检索的实例与类dict中的对象相同.的实施例1从结果变化False到True> Python 3的升级-在Python 2.