假设我们有以下类:
class K:
# classmethod creates a descriptor
@classmethod
def cm(cls, a, b, c):
pass
现在,我们通过cm
以下方式获取属性:
import random
getters = [
lambda attr_name: object.__getattribute__(K, '__dict__')[attr_name]
lambda attr_name: getattr(cm, attr_name)
]
geht = random.choice(getters)
cm = geht('cm')
什么是cm
我们刚刚得到的测试的有效方法?
(我们无法直接访问 K 类,只有cm
返回的 by geht
)
这random.choice
是非常人为的,但在某些情况下,我们有一个伪属性容器,我们想要验证它们是否都尚未解包,或者验证它们是否已解包。
人们可能会认为描述符有一个__get__()
方法,而返回的对象__get__()
没有。
但是,用__get__
修饰的函数的方法@classmethod
返回一个对象,该对象也有一个__get__
方法。
# still wrapped cm
type <class 'classmethod'>
hasattr __get__ True
hasattr __call__ False
# unwrapped cm
type <class 'method'>
hasattr __get__ True
hasattr __call__ True
我很想我们可以测试伪属性,看看它是否有__call__
方法。但是,我希望该解决方案适用于一般的描述符,而不仅仅是classmethod
s。d
对于具有方法的类的任何属性,__get__
最好确定某个引用ref
是对的引用d
还是返回的值d.__get__()
(假设d.__get__()
不返回d
)