Я хотел бы засолить несвязанный метод в Python 3.x. Я получаю эту ошибку:
>>> class A:
... def m(self):
... pass
>>> import pickle
>>> pickle.dumps(A.m)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
pickle.dumps(A.m)
File "C:\Python31\lib\pickle.py", line 1358, in dumps
Pickler(f, protocol, fix_imports=fix_imports).dump(obj)
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed
У кого-либо есть опыт с этим?
Примечание: В Python 2.x также невозможно засолить развязанные методы по умолчанию; мне удалось сделать это там некоторым странным способом, которым я не понимаю: Я записал редуктор с copy_reg
модуль для класса MethodType, который покрывает и связанные и развязанные методы. Но редуктор только решил случай связанного метода, потому что он зависел от my_method.im_self
. Загадочно это также заставило Python 2.x мочь засолить развязанные методы. Этого не происходит на Python 3.x.
Это невозможно сделать напрямую, потому что в Python 3 тип несвязанного метода пропал: это просто функция:
>>> print (type (A.m))
<class 'function'>
Функции Python не привязаны к классу, поэтому невозможно сказать, что class Am
принадлежит, просто глядя на результат выражения.
В зависимости от того, что именно вам нужно, может быть достаточно травления / распаковки кортежа (класс, имя-метода):
>>> print (pickle.loads (pickle.dumps ((A, 'm'))))
... (<class '__main__.A'>, 'm')
Вы можете получить метод (функцию) отсюда, просто используя getattr ()
:
>>> cls, method = pickle.loads (pickle.dumps ((A, 'm')))
>>> print (getattr (cls, method))
... <function m at 0xb78878ec>