tldr:メソッドは記述子であるため、これが発生する可能性があります。==
本当に等しいかどうかを比較する必要がある場合に使用します。
is
(事実上) が等しいかどうかをテストしid
ます。それでは、それをチェックしてみましょう:
>>> id(foo.bar)
4294145364L
>>> id(foo.bar)
4294145364L
>>> id(foo.bar)
4294145364L
>>> b = foo.bar
>>> id(foo.bar)
4293744796L
>>> id(foo.bar)
4293744796L
>>> b()
>>> id(foo.bar)
4293744796L
>>> b = 1
>>> id(foo.bar)
4294145364L
>>> type(foo.bar)
<type 'instancemethod'>
>>>
したがって、直接の原因は、式がfoo.bar
断続的に別のオブジェクトを返すことです。
等しいかどうかを確認する必要がある場合は、 を使用してください==
。しかし、私たちは皆、この問題の根底に到達したいと考えています。
>>> foo.__dict__['bar']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'bar'
>>> Foo.__dict__['bar']
<function bar at 0xffe2233c>
>>> getattr(foo, 'bar')
<bound method Foo.bar of <__main__.Foo object at 0xffe2f9ac>>
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0xffe2f9ac>>
>>>
バインドされたメソッドには何か特別なものがあるようです。
>>> type(foo.bar)
<type 'instancemethod'>
>>> help(type(foo.bar))
Help on class instancemethod in module __builtin__:
class instancemethod(object)
| instancemethod(function, instance, class)
|
| Create an instance method object.
|
| Methods defined here:
|
| __call__(...)
| x.__call__(...) <==> x(...)
|
| __cmp__(...)
| x.__cmp__(y) <==> cmp(x,y)
|
| __delattr__(...)
| x.__delattr__('name') <==> del x.name
|
| __get__(...)
| descr.__get__(obj[, type]) -> value
|
| __getattribute__(...)
| x.__getattribute__('name') <==> x.name
|
| __hash__(...)
| x.__hash__() <==> hash(x)
|
| __repr__(...)
| x.__repr__() <==> repr(x)
|
| __setattr__(...)
| x.__setattr__('name', value) <==> x.name = value
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __func__
| the function (or other callable) implementing a method
|
| __self__
| the instance to which a method is bound; None for unbound methods
|
| im_class
| the class associated with a method
|
| im_func
| the function (or other callable) implementing a method
|
| im_self
| the instance to which a method is bound; None for unbound methods
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __new__ = <built-in method __new__ of type object>
| T.__new__(S, ...) -> a new object with type S, a subtype of T
ここで、__get__
メソッドがリストされていることに注意してください。つまり、instancemethod
オブジェクトは記述子です。http://docs.python.org/2/reference/datamodel.html#implementing-descriptorsに従って、式foo.bar
は の結果を返します(getattr(foo,'bar').__get__(foo)
。そのため、この値は変更される可能性があります。
なぜ変更されるのかについては、実装の詳細である可能性が高いことを除いて、私には言えません。