Маринованная украшенная классная обертка
Я изо всех сил пытаюсь выбрать обернутую функцию, когда я использую пользовательский вызываемый класс в качестве оболочки.
У меня есть вызываемый класс «Dependee», который отслеживает зависимости для обернутой функции с переменной-членом «depen_on». Я хотел бы использовать декоратор, чтобы обернуть функции, а также иметь возможность выбрать полученную обернутую функцию.
Поэтому я определяю свой класс зависимых. Обратите внимание на использование functools.update_wrapper.
>>> class Dependee:
...
... def __init__(self, func, depends_on=None):
... self.func = func
... self.depends_on = depends_on or []
... functools.update_wrapper(self, func)
...
... def __call__(self, *args, **kwargs):
... return self.func(*args, **kwargs)
...
Затем я определяю свой декоратор так, чтобы он возвращал экземпляр класса-оболочки Dependee.
>>> class depends:
...
... def __init__(self, on=None):
... self.depends_on = on or []
...
... def __call__(self, func):
... return Dependee(func, self.depends_on)
...
Вот пример обернутой функции.
>>> @depends(on=["foo", "bar"])
... def sum(x, y): return x+y
...
Переменная-член кажется доступной.
>>> print(sum.depends_on)
['foo', 'bar']
Я могу вызвать функцию, как и ожидалось.
>>> print(sum(1,2))
3
Но я не могу засолить завернутый экземпляр.
>>> print(pickle.dumps(sum))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function sum at 0x7f543863fbf8>: it's not the same object as __main__.sum
Что мне не хватает? Как я могу дать pickle более подходящее имя, чтобы он мог найти экземпляр, а не исходную функцию. Обратите внимание, что ручная упаковка работает просто отлично.
>>> def sum2_func(x,y): return x+y
...
>>> sum2 = Dependee(sum2_func, depends_on=["foo", "bar"])
>>> print(sum2.depends_on)
['foo', 'bar']
>>> print(sum2(1,2))
3
>>> print(pickle.loads(pickle.dumps(sum2)).depends_on)
['foo', 'bar']