Method Reference Equality in Python
In Python, methods are unique objects created dynamically upon access. This behavior differs from that of regular functions, which are referenced by the same object regardless of when they are called.
To understand this, consider the following example:
class What: def meth(self): pass What().meth is What().meth # False
In this code, the meth methods are not equal despite referring to the same underlying function. This is because each meth object is a unique instance created at runtime.
The reason for this behavior lies in Python's attribute lookup process, where a method object is generated by calling the descriptor's (function) .__get__ method:
What.__dict__['meth'].__get__(What(), What)
This dynamic creation of method objects leads to the following observations:
Instances of the same class have different meth objects:
inst = What() inst.meth is inst.meth # False
Methods in不同的 classes are always different objects:
What.meth is Other.meth # False
Prior to Python 3.8, testing method equality using == could yield inconsistent results. However, Python 3.8 and later allow for equality comparison of methods based on their .___self__ and .___func__ attributes, if they match identically.
As a best practice, to determine if two methods represent the same underlying function, compare their .__func__ attributes:
What.meth.__func__ == What.meth.__func__ # True What().meth.__func__ == What().meth.__func__ # True (for same instance) What().meth.__func__ == What(other_instance).meth.__func__ # False (for different instances)
The above is the detailed content of Why are Python Methods Not Equal, Even if They Refer to the Same Underlying Function?. For more information, please follow other related articles on the PHP Chinese website!