Как получить имя атрибута дескриптора из __get__?
При реализации дескриптора можно использовать __set_name__
зарегистрировать, под каким именем атрибута был задан дескриптор.
Хотя предположим, что мы должны установить более одного атрибута для одного и того же дескриптора, тогда, похоже, нет никакого способа узнать, через какое имя был получен доступ к дескриптору в __get__
а также __set__
метод.
Код
class Prop:
def __init__(self):
self._names = {}
def __set_name__(self, owner, name):
print(f'Attribute \'{name}\' was set to a Prop')
if owner in self._names:
self._names[owner].append(name)
else:
self._names[owner] = [name]
def __get__(self, instance, owner):
print(f'Prop was accessed through one of those: {self._names[owner]}')
prop = Prop()
class Foo:
bar = prop
baz = prop
foo = Foo()
foo.baz
Выход
Attribute 'bar' was set to a Prop
Attribute 'baz' was set to a Prop
Prop was accessed through one of those: ['bar', 'baz']
Есть ли чистый и общий способ узнать, по какому атрибуту был получен доступ к дескриптору?
1 ответ
Решение
Есть ли чистый и общий способ узнать, по какому атрибуту был получен доступ к дескриптору?
Нет, нет чистого и общего способа.
Однако, если вы хотите получить грязный хак (пожалуйста, не делайте этого!), Вы можете избежать протокола дескриптора и просто передать имя, через которое к нему обращались вручную:
class Descriptor:
def __get__(self, instance, owner, name=None):
print(f"Property was accessed through {name}")
return 'foo'
p = Descriptor()
class Test:
a = p
b = p
def __getattribute__(self, name):
for klass in type(self).__mro__:
if name in klass.__dict__ and isinstance(klass.__dict__[name], Descriptor):
return klass.__dict__[name].__get__(self, klass, name)
else:
return object.__getattribute__(self, name)