A.attr
導致Python來調用SomeDescriptor().__get__(None, A)
所以如果你有SomeDescriptor.__get__
返回self
時inst
爲None
,然後A.attr
將返回描述:
class SomeDescriptor():
def __get__(self, inst, instcls):
if inst is None:
# instance attribute accessed on class, return self
return self
然後你
desc = type(self).attr
如果訪問描述符該屬性的名稱只作爲字符串被知道,attr_name
,那麼您將使用
desc = getattr(type(self), attr_name)
這個工程即使self
是子類的A
的實例,而
desc = self.__class__.__dict__[attr_name]
如果self
是A
實例只會工作。
class SomeDescriptor():
def __get__(self, inst, instcls):
if inst is None:
# instance attribute accessed on class, return self
return self
return 4
class A():
attr = SomeDescriptor()
def somewhere(self):
attr_name = 'attr'
desc = getattr(type(self), attr_name)
# desc = self.__class__.__dict__[attr_name] # b.somewhere() would raise KeyError
return isinstance(desc, SomeDescriptor)
這說明A.attr
返回描述符,並a.somewhere()
按預期工作:
a = A()
print(A.attr)
# <__main__.SomeDescriptor object at 0xb7395fcc>
print(a.attr)
# 4
print(a.somewhere())
# True
這說明它的工作原理爲A
子了。如果您取消註釋 desc = self.__class__.__dict__[attr_name]
,你會看到 b.somewhere()
拋出一個KeyError:
class B(A): pass
b = B()
print(B.attr)
# <__main__.SomeDescriptor object at 0xb7395fcc>
print(b.attr)
# 4
print(b.somewhere())
# True
順便說一句,即使你沒有完全控制SomeDescriptor的定義,你仍然可以把它包裝它返回一個描述符self
時inst
是無:
def wrapper(Desc):
class Wrapper(Desc):
def __get__(self, inst, instcls):
if inst is None: return self
return super().__get__(inst, instcls)
return Wrapper
class A():
attr = wrapper(SomeDescriptor)()
def somewhere(self):
desc = type(self).attr
# desc = self.__class__.__dict__[attr_name] # b.somewhere() would raise KeyError
return isinstance(desc, SomeDescriptor)
所以沒有必要使用
desc = self.__class__.__dict__[attr_name]
或
desc = vars(type(self))['attr']
從相同問題的困擾。
'type(self).__ dict __ ['attr']''怎麼樣? –