举个例子的代码:
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
- 例1:我也能猜到他们是同一个对象。 它被引用每次是否Python的制作方法的副本?
- 实施例2:预期。
- 实施例3:预期的,因为它们是不同的对象。
- 实施例4:为什么没有该输出匹配实施例2?
实施例1:
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>
最后一行表示“结合”的操作,描述符调用用于在类属性的访问,但手动写出。 在纯Python,它是这样的
class Function(object):
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
return types.MethodType(self, obj, objtype):
您还可以创建一个绑定方法方式:
>>> some_instance = SomeClass()
>>> SomeClass.__dict__['a_method'].__get__(some_instance, SomeClass)
<bound method SomeClass.a_method of <__main__.SomeClass instance at 0xcafef00d>>
实施例2:
方法比较是通过做__func__
和__self__
的方法属性。 在这种情况下,它们都是相同的:在__func__
是一样的普通的旧功能,您可以挖掘出类字典内,而__self__
是None
。 因此,尽管这些方法是不同的对象,它们的比较平等的。
实施例3:
正确。 他们是不同的对象,因此不相同。
实施例4:
正如前面提到的,比较使用__func__
和__self__
属性。 因为,在这种情况下,该结果不匹配实施例2 __self__
属性指的是不同的实例。 因为这些不同的情况下,不比较等于SomeClass
情况下,通过比较认同,因此这些方法还没有比较相等。
Python的当前版本的最后一个音符
上述一切适用于语言的当前版本,太,除了实施例1。 在Python,不再有这样的东西作为一个未结合的方法,在对象模型中,这带来不必要的复杂除去。
>>> SomeClass.a_method
<function __main__.SomeClass.a_method(self)>
>>> SomeClass.a_method is SomeClass.__dict__['a_method']
True
什么是在Python 2的“未结合的方法”现在只是一个普通的旧的函数,并通过属性访问检索的实例是相同的类中的字典的对象。 从实施例1结果的变化False
到True
> Python 3的升级-在Python 2。