"a is b"与"a is b"之间的区别是什么?和"id(a)== id(b)";在Python中? [英] What is the difference between "a is b" and "id(a) == id(b)" in Python?

查看:133
本文介绍了"a is b"与"a is b"之间的区别是什么?和"id(a)== id(b)";在Python中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

id() 内置函数提供...

The id() inbuilt function gives...

一个整数(或长整数),在该对象的生存期内,保证该整数是唯一且恒定的.

an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime.

is 运算符给出了...

对象身份

那么为什么有两个对象具有相同的id却又将False返回给is检查呢?这是一个示例:

So why is it possible to have two objects that have the same id but return False to an is check? Here is an example:

>>> class Test():
...   def test():
...     pass
>>> a = Test()
>>> b = Test()
>>> id(a.test) == id(b.test)
True
>>> a.test is b.test
False

一个更令人不安的示例:(继续上面的内容)

A more troubling example: (continuing the above)

>>> b = a
>>> b is a
True
>>> b.test is a.test
False
>>> a.test is a.test
False

但是:

>>> new_improved_test_method = lambda: None
>>> a.test = new_improved_test_method
>>> a.test is a.test
True

推荐答案

>>> b.test is a.test
False
>>> a.test is a.test
False

每次查找时都会即时创建方法.函数对象(始终是同一对象)实现描述符协议及其__get__创建绑定的方法对象.通常没有两个绑定方法是同一对象.

Methods are created on-the-fly each time you look them up. The function object (which is always the same object) implements the descriptor protocol and its __get__ creates the bound method object. No two bound methods would normally be the same object.

>>> id(a.test) == id(b.test)
True
>>> a.test is b.test
False

此示例具有欺骗性.巧合的是,第一个的结果仅为True. a.test创建一个绑定方法,并且在计算id(a.test)之后会对其进行垃圾回收,因为没有对它的任何引用. (请注意,您引用的文档说id是该对象在其生存期内 的唯一且恒定的""(强调我的).)b.test 会发生与以前的绑定方法具有相同的ID,并且由于没有其他对象现在具有相同的ID而被允许使用.

This example is deceptive. The result of the first is only True by coincidence. a.test creates a bound method and it's garbage collected after computing id(a.test) because there aren't any references to it. (Note that you quote the documentation saying that an id is "unique and constant for this object during its lifetime" (emphasis mine).) b.test happens to have the same id as the bound method you had before and it's allowed to because no other objects have the same id now.

请注意,您应该很少使用is,甚至更不应该使用id. id(foo) == id(bar)总是错误的.

Note that you should seldom use is and even less often use id. id(foo) == id(bar) is always wrong.

关于您的新示例,希望您现在能完成以下工作:

Regarding your new example, hopefully you get what it does now:

>>> new_improved_test_method = lambda: None
>>> a.test = new_improved_test_method
>>> a.test is a.test
True

在这种情况下,我们不是通过自动绑定self并返回绑定方法对象的类上的函数来快速制作方法.在这种情况下,您只需将函数存储为实例属性即可.查找没有什么特别的事情(仅当您查找类属性时才调用描述符),因此,每次查找该属性时,您都会得到存储的原始对象.

In this case, we aren't making methods on the fly from functions on the class automatically binding self and returning bound method objects. In this case, you simply store a function as an instance attribute. Nothing special happens on lookup (descriptors only get called when you look up a class attribute), so every time you look up the attribute, you get the original object you stored.

这篇关于"a is b"与"a is b"之间的区别是什么?和"id(a)== id(b)";在Python中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆