为什么方法没有引用相等性? [英] Why don't methods have reference equality?

查看:30
本文介绍了为什么方法没有引用相等性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个错误,在使用 is 时,我依赖于彼此相等的方法.事实证明并非如此:

<预><代码>>>>课什么:...定义方法(自我):... 经过>>>What.meth 是什么.meth真的>>>inst = 什么()>>>inst.meth 是 inst.meth错误的

为什么会这样?它适用于常规功能:

<预><代码>>>>def func(): 通过>>>功能是功能真的

解决方案

方法对象在每次访问时创建.函数充当 描述符,当它们.__get__ 方法被调用:

<预><代码>>>>What.__dict__['meth']<函数 What.meth at 0x10a6f9c80>>>>What.__dict__['meth'].__get__(What(), What)<绑定方法What.meth of <__main__.What object at 0x10a6f7b10>>

如果您使用的是 Python 3.8 或更高版本,则可以改用 == 等式测试.在 Python 3.8 及更高版本上,如果两个方法的 .__self__.__func__ 属性是相同的对象(因此如果它们包装相同的函数,并且绑定到相同的实例,均使用 is 进行测试).

在 3.8 之前,方法 == 的行为根据方法的实现方式不一致 - Python 方法和两种 C 方法类型之一比较 __self__ 是否相等而不是身份,而另一种 C 方法类型按身份比较 __self__ .请参阅 Python 问题 1617161.

如果您需要测试这些方法是否代表相同的底层函数,请测试它们的__func__ 属性:

<预><代码>>>>What.meth == What.meth # 函数(或 Python 2 中的未绑定方法)真的>>>What().meth == What.meth #绑定方法和函数错误的>>>What().meth == What().meth # 绑定方法与 *不同* 实例错误的>>>What().meth.__func__ == What().meth.__func__ # 函数真的

I had a bug where I was relying on methods being equal to each other when using is. It turns out that's not the case:

>>> class What:
...     def meth(self):
...         pass

>>> What.meth is What.meth
True
>>> inst = What()
>>> inst.meth is inst.meth
False

Why is that the case? It works for regular functions:

>>> def func(): pass
>>> func is func
True

解决方案

Method objects are created each time you access them. Functions act as descriptors, returning a method object when their .__get__ method is called:

>>> What.__dict__['meth']
<function What.meth at 0x10a6f9c80>
>>> What.__dict__['meth'].__get__(What(), What)
<bound method What.meth of <__main__.What object at 0x10a6f7b10>>

If you're on Python 3.8 or later, you can use == equality testing instead. On Python 3.8 and later, two methods are equal if their .__self__ and .__func__ attributes are identical objects (so if they wrap the same function, and are bound to the same instance, both tested with is).

Before 3.8, method == behaviour is inconsistent based on how the method was implemented - Python methods and one of the two C method types compare __self__ for equality instead of identity, while the other C method type compares __self__ by identity. See Python issue 1617161.

If you need to test that the methods represent the same underlying function, test their __func__ attributes:

>>> What.meth == What.meth     # functions (or unbound methods in Python 2)
True
>>> What().meth == What.meth   # bound method and function
False
>>> What().meth == What().meth # bound methods with *different* instances
False
>>> What().meth.__func__ == What().meth.__func__ # functions
True

这篇关于为什么方法没有引用相等性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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