Я пытался рассолить объект, содержащий ссылки на статические методы класса. Рассол не работает (например, на module.MyClass.foo
), заявив, что он не может быть маринован, поскольку module.foo
не существует.
я придумал следующее решение, используя объект-оболочку, чтобы найти функцию при вызове, сохранение класса контейнера и функции имя:Травление статического метода в Python
class PicklableStaticMethod(object):
"""Picklable version of a static method.
Typical usage:
class MyClass:
@staticmethod
def doit():
print "done"
# This cannot be pickled:
non_picklable = MyClass.doit
# This can be pickled:
picklable = PicklableStaticMethod(MyClass.doit, MyClass)
"""
def __init__(self, func, parent_class):
self.func_name = func.func_name
self.parent_class = parent_class
def __call__(self, *args, **kwargs):
func = getattr(self.parent_class, self.func_name)
return func(*args, **kwargs)
мне интересно, хотя, есть лучше - более стандартный способ - рассолить такой объект? Я не хочу, чтобы внести изменения в глобальной pickle
процесса (с использованием copy_reg
, например), но следующий шаблон будет велик: класс MyClass (объект): @picklable_staticmethod Защиту Foo(): «сделано» печати
Мои попытки были безуспешными, особенно потому, что я не смог извлечь класс владельца из функции foo
. Я даже хотел согласиться на явные спецификации (например, @picklable_staticmethod(MyClass)
), но я не знаю, как обращаться к классу MyClass
, где он определен.
Любые идеи были бы замечательными!
Yonatan
это не сработает, если исходный класс недоступен, который (я думаю) побеждает цель травления и рассыпания статического метода - вы разрешаете его мариноваться, но вам нужен весь класс, чтобы его разложить. –
попробовать, что, например: импорт рассола класса MyClass (объект): @PickleableStaticMethod Защиту DoSomething (а, б): печатающих а, б маринованных = pickle.dumps (MyClass.dosomething) дель MyClass stm = pickle.loads (маринованный) –
Я думаю, я мог бы просто сказать что-то совершенно неправильное там, маринованные работы совершенно разные с funcs, которые я ожидал. игнорировать мои последние два комментария: -/ –