この質問は、(少なくとも) CPython 2.7.2 および 3.2.2 に関するものです。
と を次のように定義するClass
とobj
します。
class Class(object):
def m(self):
pass
@property
def p(self):
return None
@staticmethod
def s():
pass
obj = Class()
短縮版
False
次のコードがそれぞれに対して出力されるのはなぜprint()
ですか?
print(Class.__dict__ is Class.__dict__)
print(Class.__subclasshook__ is Class.__subclasshook__)
print(Class.m is Class.m)
print(obj.__delattr__ is obj.__delattr__)
print(obj.__format__ is obj.__format__)
print(obj.__getattribute__ is obj.__getattribute__)
print(obj.__hash__ is obj.__hash__)
print(obj.__init__ is obj.__init__)
print(obj.__reduce__ is obj.__reduce__)
print(obj.__reduce_ex__ is obj.__reduce_ex__)
print(obj.__repr__ is obj.__repr__)
print(obj.__setattr__ is obj.__setattr__)
print(obj.__sizeof__ is obj.__sizeof__)
print(obj.__str__ is obj.__str__)
print(obj.__subclasshook__ is obj.__subclasshook__)
print(obj.m is obj.m)
(これは Python 2 の場合です。Python 3 の場合は、print()
forを省略して、、、、、およびに同様の s をClass.m
追加します)print()
obj.__eq__
obj.__ge__
obj.__gt__
obj.__le__
obj.__lt__
obj.__ne__
一方、次のコードTrue
がそれぞれに対して出力されるのはなぜprint()
ですか?
print(Class.__class__ is Class.__class__)
print(Class.__delattr__ is Class.__delattr__)
print(Class.__doc__ is Class.__doc__)
print(Class.__format__ is Class.__format__)
print(Class.__getattribute__ is Class.__getattribute__)
print(Class.__hash__ is Class.__hash__)
print(Class.__init__ is Class.__init__)
print(Class.__module__ is Class.__module__)
print(Class.__new__ is Class.__new__)
print(Class.__reduce__ is Class.__reduce__)
print(Class.__reduce_ex__ is Class.__reduce_ex__)
print(Class.__repr__ is Class.__repr__)
print(Class.__setattr__ is Class.__setattr__)
print(Class.__sizeof__ is Class.__sizeof__)
print(Class.__str__ is Class.__str__)
print(Class.__weakref__ is Class.__weakref__)
print(Class.p is Class.p)
print(Class.s is Class.s)
print(obj.__class__ is obj.__class__)
print(obj.__dict__ is obj.__dict__)
print(obj.__doc__ is obj.__doc__)
print(obj.__module__ is obj.__module__)
print(obj.__new__ is obj.__new__)
print(obj.__weakref__ is obj.__weakref__)
print(obj.p is obj.p)
print(obj.s is obj.s)
(これは Python 2 の場合です。Python 3の場合は、 、 、 、、、、およびに同様print()
の s を追加します)Class.__eq__
Class.__ge__
Class.__gt__
Class.__le__
Class.__lt__
Class.__ne__
Class.m
ロングバージョン
2 回続けて要求するとid(obj.m)
、(当然のことながら) 同じオブジェクト ID が 2 回取得されます。
>>> id(obj.m)
139675714789856
>>> id(obj.m)
139675714789856
ただし、 を要求しid(obj.m)
、 を参照するいくつかの式を評価してから再度obj.m
要求するid(obj.m)
と、(常にではありませんが) オブジェクト ID が変更されていることがわかります。変化する状況の中には、id(obj.m)
もう一度要求すると ID が元の値に戻るものもあります。元に戻らない場合、id(obj.m)
呼び出し間で式を繰り返すと、明らかに ID が 2 つの観測値の間で交互に表示されます。
オブジェクト ID が変更されない例を次に示します。
>>> print(obj.m); id(obj.m)
<bound method Class.m of <__main__.Class object at 0x7f08c96058d0>>
139675714789856
>>> obj.m is None; id(obj.m)
False
139675714789856
>>> obj.m.__func__.__name__; id(obj.m)
'm'
139675714789856
>>> obj.m(); id(obj.m)
139675714789856
以下は、オブジェクト ID が変更されてから元に戻る例です。
>>> obj.m; id(obj.m); id(obj.m)
<bound method Class.m of <__main__.Class object at 0x7f08c96058d0>>
139675715407536
139675714789856
オブジェクト ID が変更された後、元に戻らない例を次に示します。
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675715407536
139675715407536
以下は同じ例で、交互の動作を示すためにオペラント式が数回繰り返されています。
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675714789856
139675714789856
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675715407536
139675715407536
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675714789856
139675714789856
したがって、質問全体は次の部分で構成されます。
それらの属性を変更しない式の副作用として、どのような種類の属性がアイデンティティを変更する可能性がありますか?
その変化のきっかけとなる表情とは?
このような変化をもたらすメカニズムとは?
過去のアイデンティティはどのような条件下でリサイクルされるのか?
最初の ID が無期限にリサイクルされないのはなぜでしょうか?
これは文書化されていますか?