0

假设我们有以下类:

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__方法。但是,我希望该解决方案适用于一般的描述符,而不仅仅是classmethods。d对于具有方法的类的任何属性,__get__最好确定某个引用ref是对的引用d还是返回的值d.__get__()(假设d.__get__()不返回d

4

1 回答 1

0

没有通用的解决方案。任何可能的描述符也是可能的__get__返回值。您需要更多信息来确定这一点,而不仅仅是对象。

于 2018-05-02T04:08:54.713 回答