python属性の検索優先度
3402 ワード
要素を取得すると、実際に呼び出されるのはobject._です.getattribute__(key)検索優先度とは実際にobject._getattribute__実装された
Data DescriptorとNon-data Descriptorの違いは、インスタンス辞書エントリの上書きと計算順序に反映されます.インスタンス辞書にData Descriptorと同じ名前のプロパティが含まれている場合は、Data Descriptorが優先されます.インスタンス辞書にNon-data Descriptorと同じ名前のプロパティが含まれている場合は、インスタンス辞書が優先されます.同時定義_get__()と_set__()メソッド、そして_set__()呼び出し時にAttributeError例外を投げ出すと、読み取り専用のData Descriptorを作成できます.例外を放出する_を定義するだけです.set__()メソッドは,そのオブジェクトをData Descriptorにするのに十分である.
メソッドは実際には非データ記述子です.
次はobject._getattribute__(key)の偽コードといくつかのインスタンスは、勝手に遊んでいます.
object.__getattribute__(key)のダミーコード
Data DescriptorとNon-data Descriptorの違いは、インスタンス辞書エントリの上書きと計算順序に反映されます.インスタンス辞書にData Descriptorと同じ名前のプロパティが含まれている場合は、Data Descriptorが優先されます.インスタンス辞書にNon-data Descriptorと同じ名前のプロパティが含まれている場合は、インスタンス辞書が優先されます.同時定義_get__()と_set__()メソッド、そして_set__()呼び出し時にAttributeError例外を投げ出すと、読み取り専用のData Descriptorを作成できます.例外を放出する_を定義するだけです.set__()メソッドは,そのオブジェクトをData Descriptorにするのに十分である.
メソッドは実際には非データ記述子です.
次はobject._getattribute__(key)の偽コードといくつかのインスタンスは、勝手に遊んでいます.
class demo(object):#
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def __get__(self, instance, owner):
return owner.__dict__[type(self).__name__](instance, *self.args, **self.kwargs)
class Descriptor(object):
def __get__(self, instance, owner):
return 'Descriptor'
def __set__(self, instance, value):
pass
class FOO(object):
def __getattr__(self, item):
return '__getattr__'
def __init__(self, *args, **kwargs):
pass
# attr = Descriptor()
demo = demo()
# def demo(self):
# pass
def __del__(self):
pass
foo = FOO(1, 2, 3)
# foo.attr = 'instance attr'
# FOO.attr = 'class attr'
# type(foo).__dict__['attr'].__get__(foo, type(foo))
# FOO.__dict__['attr'].__get__(None, FOO)
print foo.attr
print FOO.attr
print FOO.__dict__['demo'] #
print FOO.demo #
print foo.demo # >
print FOO.__dict__['demo'].__get__(None, FOO) == FOO.demo #True
print type(foo).__dict__['demo'].__get__(foo, type(foo)) == foo.demo # #True
object.__getattribute__(key)のダミーコード
def __getattribute__(self, key):
# self
if type(type) == type(self):
pass
# , 1, __getattr__2, 。(unbound method)
# self
else:
#
_attr = type(self).__dict__.get(key)
if _attr and hasattr(_attr, '__get__') and hasattr(_attr, '__set__'):
_value = type(self).__dict__[key]
if hasattr(_value, '__get__'):
return _value.__get__(self, type(self))
return _value
del _attr
#
_attr = self.__dict__.get(key)
if _attr:
return _attr
del _attr
#
_attr = type(self).__dict__.get(key)
if _attr and hasattr(_attr, '__get__'):
_value = type(self).__dict__[key]
if hasattr(_value, '__get__'):
return _value.__get__(self, type(self))
return _value
del _attr
#
_attr = type(self).__dict__.get(key)
if _attr:
return _attr
#
for FClass in self.__class__.__mro__:
_attr = FClass.__dict__.get(key)
if _attr:
return _attr
# __getattr__
if hasattr(self, '__getattr__'):
return self.__getattr__(key)
else:
raise AttributeError('type object "{1}" has no attribute "{2}"'.format(str(self.__class__), key))