Python 为什么'obj.method'是obj.\u class\u method'是False

Python 为什么'obj.method'是obj.\u class\u method'是False,python,Python,我正在阅读python类的文档,我面对的是9.6。写入的私有变量 由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称混乱的机制的支持有限。格式为uuu spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为u classname uuuu spam,其中classname是带前导下划线的当前类名。只要标识符出现在类的定义中,就可以在不考虑标识符的语法位置的情况下进行修改 这让我很好奇,obj.update就是obj.\u Mappi

我正在阅读python类的文档,我面对的是9.6。写入的私有变量

由于类私有成员有一个有效的用例(即避免名称与子类定义的名称发生名称冲突),因此对这种称为名称混乱的机制的支持有限。格式为uuu spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为u classname uuuu spam,其中classname是带前导下划线的当前类名。只要标识符出现在类的定义中,就可以在不考虑标识符的语法位置的情况下进行修改

这让我很好奇,
obj.update就是obj.\u Mapping\u update
应该返回True。但事实并非如此。我检查了他们两人的身份,他们都是一样的。所以这里发生了什么事

In [1]: class Mapping: 
   ...:     def __init__(self, iterable): 
   ...:         self.items_list = [] 
   ...:         self.__update(iterable) 
   ...:  
   ...:     def update(self, iterable): 
   ...:         for item in iterable: 
   ...:             self.items_list.append(item) 
   ...:  
   ...:     __update = update   # private copy of original update() method 
   ...:                                                                                                                                                                                                             

In [2]: obj = Mapping([])                                                                                                                                                                                           

In [3]: obj.update == obj._Mapping__update                                                                                                                                                                          
Out[3]: True

In [4]: print(id(obj.update), id(obj._Mapping__update))                                                                                                                                                             
139655901847816 139655901847816

In [5]: obj.update is obj._Mapping__update                                                                                                                                                                          
Out[5]: False

访问实例的方法时,每次都会返回一个新的绑定方法:

>>> class X:
...     def foo(self): pass
...     __foo = foo
...
>>> inst = X()
>>> a = inst.foo
>>> b = inst._X__foo
>>> a
<bound method X.foo of <__main__.X object at 0x7f62f41144a8>>
>>> b
<bound method X.foo of <__main__.X object at 0x7f62f41144a8>>
请注意,如果直接对属性调用
id()
,每次都会创建并丢弃一个新的绑定方法,并且不能保证Python不会重复使用以前的id。因此,在进行此类比较之前,将对象保存到一个变量非常重要

要比较基础方法的标识,应使用以下类:

>>> X._X__foo is X.foo
True
>>> X._X__foo is X.foo
True