Why is this false? `SomeClass.method is SomeClass.method`
以该代码为例:
1 2 3 4 5 6 7 8 | 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:
Does Python make a copy of the method each time it is referenced?
是的,或多或少。这是通过描述符协议完成的。
1 2 3 4 5 6 | >>> 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中,它就像这样
1 2 3 4 | class Function(object): def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" return types.MethodType(self, obj, objtype): |
您也可以这样创建绑定方法:
1 2 3 | >>> some_instance = SomeClass() >>> SomeClass.__dict__['a_method'].__get__(some_instance, SomeClass) <bound method SomeClass.a_method of <__main__.SomeClass instance at 0xcafef00d>> |
例2:
方法比较是通过方法上的
对的。它们是不同的对象,因此不相同。
例4:如前所述,比较使用
上面提到的所有内容也适用于该语言的当前版本,示例1除外。在Python中,不再存在未绑定的方法,对象模型中不必要的复杂性被移除了。
1 2 3 4 | >>> SomeClass.a_method <function __main__.SomeClass.a_method(self)> >>> SomeClass.a_method is SomeClass.__dict__['a_method'] True |
python 2中的"未绑定方法"现在只是一个普通的旧函数,通过属性访问检索到的实例与类dict中的对象相同。在python2->python 3升级中,示例1的结果是从