Я реализовал метакласс, который удаляет атрибуты класса для классов, созданных с его помощью, и строит методы на основе данных из этих аргументов, а затем прикрепляет эти динамически созданные методы непосредственно к объекту класса (рассматриваемый класс позволяет легко определять объекты веб-форм для использовать в среде веб-тестирования). Он работал просто отлично, но теперь мне нужно добавить более сложный тип метода, который, чтобы сохранить чистоту, я реализовал как вызываемый класс. К сожалению, когда я пытаюсь вызвать вызываемый класс для экземпляра, он рассматривается как атрибут класса, а не как метод экземпляра, и при вызове получает только свой собственный self
. Я понимаю, почему это происходит, но я надеялся, что у кого-то может быть лучшее решение, чем те, которые я придумал. Упрощенная иллюстрация проблемы:
class Foo(object):
def __init__(self, name, val):
self.name = name
self.val = val
self.__name__ = name + '_foo'
self.name = name
# This doesn't work as I'd wish
def __call__(self, instance):
return self.name + str(self.val + instance.val)
def get_methods(name, foo_val):
foo = Foo(name, foo_val)
def bar(self):
return name + str(self.val + 2)
bar.__name__ = name + '_bar'
return foo, bar
class Baz(object):
def __init__(self, val):
self.val = val
for method in get_methods('biff', 1):
setattr(Baz, method.__name__, method)
baz = Baz(10)
# baz.val == 10
# baz.biff_foo() == 'biff11'
# baz.biff_bar() == 'biff12'
Я подумал о:
- Использование дескриптора, но это кажется более сложным, чем здесь необходимо
- Использование замыкания внутри фабрики для
foo
, но вложенные замыкания в большинстве случаев являются уродливыми и грязными заменами объектов, imo - Оборачивая экземпляр
Foo
в метод, который передает егоself
вниз экземпляруFoo
какinstance
, в основном декоратор, это то, что я на самом деле добавляю кBaz
, но это кажется излишним и в основном просто более сложным способом сделать то же самое, что и ( 2)
Есть ли лучший способ, чем любой из них, чтобы попытаться выполнить то, что я хочу, или я должен просто укусить пулю и использовать какой-то шаблон типа фабрики закрытия?