Какой эффективный способ проверить, был ли дескриптор уже развернут или нет?

Предположим, у нас есть следующий класс:

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 вернулся 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)

1 ответ

Там нет общего решения. Любой возможный дескриптор также возможен __get__ возвращаемое значение Вам нужно больше информации, чем просто объект, чтобы определить это.

Другие вопросы по тегам