Какой эффективный способ проверить, был ли дескриптор уже развернут или нет? - PullRequest
0 голосов
/ 02 мая 2018

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

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 Ответ

0 голосов
/ 02 мая 2018

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

...