Я вложил в подкласс встроенный класс property
(назовите его SpecialProperty
), чтобы добавить к нему больше полей:
class SpecialProperty(property):
extra_field_1 = None
extra_field_2 = None
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
super().__init__(fget, fset, fdel, doc)
def make_special_property(func):
prop = SerialisableProperty(fget=func)
return prop
и я могу использовать его так же, как встроенный property()
декоратор:
@my_module.make_special_property
def get_my_property(self): return self._my_property
Теперь я хочу дополнительно специализировать мои SpecialProperty
экземпляры, заполняя одно из дополнительных полей, добавленных в класс, произвольным значением.
Возможно ли в Python написать декоратор, который будет возвращать свойство, также принимая дополнительные параметры?
Я бы хотел сделать это через декоратор, потому что именно здесь и когда информация наиболее актуальна, однако я застрял в ней. Я подозреваю, что это относится к области декораторов с аргументами , которые были хорошо документированы ( Декораторы с аргументами? (Переполнение стека) или Python Decorators II: Аргументы декоратора (artima .com) , чтобы привести только несколько источников), однако я не могу применить тот же шаблон к моему делу.
Вот как я пытаюсь это написать:
@my_module.make_special_property("example string")
def get_my_property(self): return self._my_property
А по классу объявив get_my_property
:
>>> DeclaringClass.my_property
<SpecialProperty object at 0x...>
>>> DeclaringClass.my_property.extra_field_1
'example string'
Так как я делаю properties
, декорированный член класса должен поменяться экземпляром SpecialProperty
, и, следовательно, больше не должен вызываться - поэтому я не могу применить шаблон «вложенной оболочки» для разрешение декоратору с аргументами.
Неработающий пример:
def make_special_property(custom_arg_1):
def wrapper(func):
prop = SerialisableProperty(fget=func)
prop.extra_field_1 = custom_arg_1
return prop
return wrapper # this returns a callable (function)
Мне не нужно возвращать вызываемый объект, если я хочу, чтобы свойство возвращало экземпляр SpecialProperty
, но я не могу вызвать return wrapper(func)
по понятным причинам.