请考虑以下事项

class A(object):
    def foo(self):
        pass


a = A()
# accessing a's foo seems consistent
init1 = a.foo
init2 = a.foo
assert init1 == init2
assert id(a.foo) == id(a.foo)

# Or is it?
foos= [a.foo for i in range(10)]
ids = [id(foo) for foo in foos]
for i, id_ in enumerate(ids):
    for j, id__ in enumerate(ids):
        if i != j:
            assert id_ != id__

看起来id(a.foo)可以等于id(a.foo),也不能等于id(a.foo),但我不能理解它什么时候相同,什么时候不相同.

请解释一下这是怎么回事.

推荐答案

每次访问实例方法属性时,都会发生从函数到实例方法的转换,因此ID应该每次都不同,至少在创建新对象的意义上是不同的.(有关方法转换和描述符的详细信息,请参见Python Data Model)

问题是这样做:

assert id(a.foo) == id(a.foo)

有时候,Python垃圾收集器的工作速度非常快,即使在一个表达式中,两个不同的对象也可以具有相同的id,因为一旦完成id(),对象就已经被回收了.

如果您执行此操作:

assert id(init1) == id(init2)

您将看到它们实际上具有不同的ID.


更新:为了解决为什么init1 == init2等于True的问题:init1init2是引用相同类中的相同函数的方法包装器对象,因此方法包装器__eq__()将它们视为相等.

Python相关问答推荐

Pandas 在最近的日期合并,考虑到破产

根据在同一数据框中的查找向数据框添加值

如何根据参数推断对象的返回类型?

如何在Windows上用Python提取名称中带有逗号的文件?

Pandas - groupby字符串字段并按时间范围 Select

django禁止直接分配到多对多集合的前端.使用user.set()

无法定位元素错误404

组/群集按字符串中的子字符串或子字符串中的字符串轮询数据框

我想一列Panadas的Rashrame,这是一个URL,我保存为CSV,可以直接点击

如何在Python Pandas中填充外部连接后的列中填充DDL值

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

python的文件. truncate()意外地没有截断'

如何在Django模板中显示串行化器错误

查找查找表中存在的列值组合

如何在python tkinter中绑定键盘上的另一个回车?

大型稀疏CSR二进制矩阵乘法结果中的错误

对于数组中的所有元素,Pandas SELECT行都具有值

查找数据帧的给定列中是否存在特定值

try 在单个WITH_COLUMNS_SEQ操作中链接表达式时,使用Polars数据帧时出现ComputeError

如何在开始迭代自定义迭代器类时重置索引属性?