les*_*ana 13 python comparison identity
对象标识的运算符
is和is not测试:x is y当且仅当x和y是同一个对象时才是真的.x is not y产生反向真值.
我们试试看:
>>> def m():
... pass
...
>>> m is m
True
Run Code Online (Sandbox Code Playgroud)
由于自动垃圾收集,空闲列表和描述符的动态特性,您可能会注意到
is操作符的某些使用中看似异常的行为,例如涉及实例方法或常量之间的比较.查看他们的文档了解更多信息.
>>> class C:
... def m():
... pass
...
>>> C.m is C.m
False
Run Code Online (Sandbox Code Playgroud)
我搜索了更多的解释,但我找不到任何解释.
为什么是C.m is C.m假的?
我使用的是Python 2.x. 如下面的答案中所述,在Python 3.x中C.m is C.m是真的.
Kat*_*iel 18
当你要求一个实例的属性作为一个函数时,你得到一个绑定方法:一个可调用的对象,它包装在类中定义的函数并将实例作为第一个参数传递.在Python 2.x中,当您要求类的属性是一个函数时,您会得到一个类似的代理对象,称为未绑定方法:
>>> class A: m = lambda: None
...
>>> A.m
<unbound method A.<lambda>>
Run Code Online (Sandbox Code Playgroud)
当您要求它时,会创建此特殊对象,而不会在任何地方缓存.这意味着当你这样做
>>> A.m is A.m
False
Run Code Online (Sandbox Code Playgroud)
您正在创建两个不同的未绑定方法对象并测试它们的身份.
请注意
>>> x = A.m
>>> x is x
True
Run Code Online (Sandbox Code Playgroud)
和
>>> A.m.im_func is A.m.im_func
True
Run Code Online (Sandbox Code Playgroud)
工作得很好.(im_func是未绑定方法对象包装的原始函数.)
顺便说一句,在Python 3.x中,C.m is C.m是True,因为完全删除了(有点无意义的)未绑定方法代理对象,您只需获得您定义的原始函数.
这只是Python中属性查找非常动态的一个例子:当你要求对象的属性时,可以运行任意Python来计算该属性的值.这是另一个测试失败的例子,其中更清楚的原因是:
>>> class ChangingAttribute(object):
... @property
... def n(self):
... self._n += 1
... return self._n
...
... def __init__(self):
... self._n = 0
...
>>> foo = ChangingAttribute()
>>> foo.n
1
>>> foo.n
2
>>> foo.n
3
>>> foo.n is foo.n
False
>>> foo.n
6
Run Code Online (Sandbox Code Playgroud)
小智 6
我假设您使用的是Python 2?在Python 3中,C.m is C.m(但C().m is C().m仍然是假的).如果你只是C.m在REPL 进入,我打赌你会看到类似的东西<UnboundMethod... >.除了检查之外,UnboundMethod包装器的功能很少isinstance(self, cls).(对于这个创建一个包装器似乎没有意义吗?它是,所以它在Python 3中被删除 - C.m只是一个函数).每当访问该方法时,都会按需创建一个新的包装器实例 - C.m创建一个,另一个C.m创建另一个.因为他们是不同的例子,C.m is not C.m.
密切相关的是绑定方法,它们允许您执行f = obj.method; f(*args)但也会导致instance.method is not instance.method.在实例化时,类中定义的所有函数(读取:所有方法,当然除了monkeypatched之外)都成为实例的属性.当您访问它们时,您将获得普通函数周围的包装器(绑定方法)的新实例.这个包装器会记住instance(self),并且(arg1, arg2, ..., argN)只需将这些函数调用到函数中 - 并self添加为第一个参数.您通常不会注意到因为您立即调用该方法 - 但这是允许self隐式传递而不诉诸语言级欺骗的原因.
有关更多详细信息,请参阅Python的历史记录,以及历史记录.
| 归档时间: |
|
| 查看次数: |
329 次 |
| 最近记录: |