栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

绑定和未绑定方法对象的id()-有时对于不同的对象相同,有时对于相同的对象不同

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

绑定和未绑定方法对象的id()-有时对于不同的对象相同,有时对于相同的对象不同

每当您通过

instance.name
(和在Python
2中
class.name
)通过查找方法时,都会重新创建该方法对象。Python每次都使用描述符协议将函数包装在方法对象中。

因此,当您查找时

id(C.foo)
,将创建一个新的方法对象,您将检索其ID(内存地址),然后 再次丢弃该方法对象
。然后,您查找
id(cobj.foo)
,创建了一个新方法对象,该对象重新使用了现在释放的内存地址,并且看到了相同的值。然后再次丢弃该方法(当参考计数降至0时收集垃圾)。

接下来,您将对

C.foo
未绑定方法的引用存储在变量中。现在不释放内存地址(引用计数为1,而不是0),然后通过查找必须使用新内存位置的方法来创建
第二个 方法实例
cobj.foo
。因此,您将获得两个不同的值。

请参阅有关文档

id()

返回对象的“身份”。这是一个整数(或长整数),在此对象的生存期内,此整数保证是唯一且恒定的。
具有非重叠生存期的两个对象可能具有相同的

id()

CPython实现细节 :这是对象在内存中的地址。

强调我的。

您可以通过

__dict__
类的属性使用对函数的直接引用来重新创建方法,然后调用
__get__
描述符方法:

>>> class C(object):...     def foo(self):...         pass... >>> C.foo<unbound method C.foo>>>> C.__dict__['foo']<function foo at 0x1088cc488>>>> C.__dict__['foo'].__get__(None, C)<unbound method C.foo>>>> C.__dict__['foo'].__get__(C(), C)<bound method C.foo of <__main__.C object at 0x1088d6f90>>

请注意,在Python 3中,删除了整个未绑定/绑定方法的区别;您将获得一个函数,在此之前,您将获得一个未绑定的方法,否则将获得一个方法,在此方法中,方法
始终是 绑定的:

>>> C.foo<function C.foo at 0x10bc48dd0>>>> C.foo.__get__(None, C)<function C.foo at 0x10bc48dd0>>>> C.foo.__get__(C(), C)<bound method C.foo of <__main__.C object at 0x10bc65150>>

此外,Python
3.7添加了一个新的

LOAD_METHOD
-
CALL_METHOD
操作码对,以精确地替换当前的
LOAD_ATTRIBUTE
-
CALL_FUNCTION
操作码对,以避免每次都创建一个新的方法对象。这种优化变换executon路径
instance.foo()
type(instance).__dict__['foo'].__get__(instance,type(instance))()
type(instance).__dict__['foo'](instance)
“手动”,所以在该实例通过直接向功能对象。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/669074.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号