Вызовите __get__ дескриптора Python с дополнительными аргументами?

Можно ли передать дополнительные аргументы при получении дескриптора?

Например, я хотел бы иметь:

class Element(object):
    def __init__(self, text='initial'):
        self.text = text

    def __get__(self, instance, owner, extra_text=''):
        print self.text + instance.name + extra_text

И тогда сможете использовать его так:

class MyClass(object):
    elem1 = Element()
    elem2 = Element(text='override')

    def __init__(self, name):
        self.name = name

    def print_elems(self):
        self.elem1
        self.elem1(extra_text='extra')
        self.elem2
        self.elem2(extra_text='extra')

MyClass('name').print_elems()

И тогда получите:

initialname
initialnameextra
overridename
overridenameextra

Есть ли способ сделать эту работу? Я даже пытался позвонить elem1.__get__(self, self.__class__, extra_text='extra) и делая extra_text обязательный параметр, но не мог придумать, как на самом деле его предоставить?

Если не с дескрипторами, есть ли альтернативный способ достижения этого синтаксиса?

Спасибо!

1 ответ

Чтобы вызвать get() с чем угодно, кроме автоматических аргументов, вам нужно получить доступ к экземпляру дескриптора. Для этого... Шаг 1: добавьте в качестве первой строки get():

if instance is None:
    return self

Это довольно распространенное дополнение к методу.

Шаг 2: Получая доступ к дескриптору, получите его из класса вместо экземпляра:

MyClass.elem1
MyClass.elem1

или же

type(my_inst).elem1
type(my_inst).elem1

Шаг 3: Вызовите get () явно, передавая нужный аргумент.

Гадкий и многословный; избегать так долго, как вы можете.

У меня вышла книга о дескрипторах, которую можно найти по адресу http://www.lulu.com/spotlight/jacobz_20 Она может помочь вам разобраться в этом, если вы запутались.

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