Маринованная украшенная классная обертка

Я изо всех сил пытаюсь выбрать обернутую функцию, когда я использую пользовательский вызываемый класс в качестве оболочки.

У меня есть вызываемый класс «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']

Ответы на вопрос(2)

Ваш ответ на вопрос