@MrChen

Как получить название объекта дескриптора и класса в котором дескриптор инициализируется python?

Приветствую! Появилось два вопрос: как в дескрипторе получить имя объекта самого дескриптора? Как в дескрипторе получить имя класса в котором был инициализирован дескриптор?

Для примера прилагаю код:
class Descriptor:
	def __init__(self):
		#Здесь нужно получить название объекта "b" и название класса "A"

class A:
	b = Descriptor()
  • Вопрос задан
  • 653 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Sir_MaNiAl
Дескриптор сначала инстанцируется и инициализируется, и только потом ему присваевается имя A.b. Так что если имя класса и дескриптора не передать явно - никак.
Если уж это так принципиально, можно передать эти значения неявно, например, с помощью метакласса. Но это значительно усложнит восприятие кода, сто раз спросите себя нужно ли это вам.
Пример реализации через метакласс:
#Псевдо-дескриптор сохранит все переданные аргументы и
#...передаст их метаклассу для инициализации дескриптора
class PseudoDescriptor:
    __slots__ = ('args', 'kwargs')

    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs


class MyMeta(type):
    def __init__(cls, class_name, bases, attrs):
        for key, value in attrs.items():
            #Ищем псевдо-дескрипторы
            if isinstance(value, PseudoDescriptor):
                # Заменяем на дескрипторы
                # Инициализируем дескрипторы с известными именами
                descriptor = Descriptor(parent_class_name=class_name,
                                        instance_name=key,
                                        *value.args,
                                        **value.kwargs)
                setattr(cls, key, descriptor)
###
###


class Descriptor:
    def __init__(self, parent_class_name, instance_name, foo, bar=None):
        #Название объекта лежит в instance_name
        #Название класса лежит в parent_class_name
        #foo и bar - какие-то аргументы, передающиеся явно при объявлении класса
        print('Имя класса:', parent_class_name, '\nИмя аттрибута:', instance_name)


class TestClass(metaclass=MyMeta):
    #Вместо Descriptor используем PseudoDescriptor
    #Метакласс MyMeta извлечет из него переданные данные
    #... и создаст вместо этого объект класса Descriptor
    test_attribute = PseudoDescriptor(foo=1)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы