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

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

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. Для любого атрибута d класса, имеющего метод __get__, было бы неплохо определить, является ли некоторая ссылка ref ссылкой на d или значением, возвращаемым d.__get__() (при условии, что d.__get__() не возвращает d)

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
32
1

Ответы 1

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

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