Какой эффективный способ проверить, был ли дескриптор уже развернут или нет?
Предположим, у нас есть следующий класс:
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__
возвращаемое значение Вам нужно больше информации, чем просто объект, чтобы определить это.