为什么这是假的? SomeClass.method是SomeClass.method [英] Why is this false? `SomeClass.method is SomeClass.method`
问题描述
以下面的代码为例:
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不匹配?
- Example 1: I would have guessed that they were the same object. Does Python make a copy of the method each time it is referenced?
- Example 2: Expected.
- Example 3: Expected, since they are different objects.
- Example 4: Why doesn't this output match example 2?
推荐答案
示例1:
Someclass.a_method
是未绑定方法.这些在当今的Python中甚至都不存在,因此请认为这是无用的历史课程.
Example 1:
Someclass.a_method
is an unbound method. These don't even exist in Python nowadays, so consider this a useless history lesson.
Python每次被引用时都会复制该方法吗?
Does Python make a copy of the method each time it is referenced?
是,或多或少.这是通过描述符协议完成的.
Yes, more or less. This is done via descriptor protocol.
>>> 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中,就像这样
The last line is showing the "binding" operation that descriptors invoke for attribute access on a class, but written out manually. In pure Python, it's something like this
class Function(object):
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
return types.MethodType(self, obj, objtype):
您还可以通过以下方式创建绑定方法:
You can also create a bound method that way:
>>> 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__
是可以从类dict中挖掘出来的相同的普通旧函数,而__self__
是None
.因此,尽管这些方法是不同的对象,但它们的比较是相等的.
Example 2:
Method comparison is done via the __func__
and __self__
attributes on the methods. In this case, they are both identical: the __func__
is the same plain old function you can dig out of the class dict, and the __self__
is None
. So despite these methods being different objects, they compare equal.
正确.它们是不同的对象,因此并不相同.
Correct. They are different objects, and hence not identical.
如前所述,比较使用的是__func__
和__self__
属性.结果与示例2不匹配,因为在这种情况下,__self__
属性引用的是不同的实例.那些不同的实例不相等,因为SomeClass
实例按身份比较,因此这些方法也不相等.
As mentioned earlier, comparison is using the __func__
and __self__
attributes. The result doesn't match example 2 because, in this case, the __self__
attributes are referring to different instances. Those different instances don't compare equal because SomeClass
instances compare by identity, therefore the methods also don't compare equal.
除示例1 外,上述所有内容均适用于该语言的当前版本.在Python中,不再存在未绑定方法之类的东西,对象模型中这种不必要的复杂性已被消除.
Everything mentioned above applies to the current version of the language, too, except for Example 1. In Python, there is no longer such thing as an unbound method, this unnecessary complication in the object model was removed.
>>> SomeClass.a_method
<function __main__.SomeClass.a_method(self)>
>>> SomeClass.a_method is SomeClass.__dict__['a_method']
True
Python 2中的未绑定方法"现在只是一个普通的旧函数,并且通过属性访问检索的实例与dict类中的对象相同.在Python 2-> Python 3升级中,示例1 结果从False
变为True
.
What was an "unbound method" in Python 2 is now just a plain old function, and the instance retrieved via attribute access is identical to the object in the class dict. The Example 1 result changes from False
to True
in a Python 2 -> Python 3 upgrade.
这篇关于为什么这是假的? SomeClass.method是SomeClass.method的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!