Это правильный способ выбора методов экземпляра? Если да, то почему нет в Python 3? - PullRequest
5 голосов
/ 05 июля 2011

Методы экземпляра не могут автоматически выбираться как в Python 2, так и в Python 3.

Мне нужно выбрать методы экземпляра с помощью Python 3, и я перенес пример кода Стивена Бетарда на Python 3:

import copyreg
import types

def _pickle_method(method):
    func_name = method.__func__.__name__
    obj = method.__self__
    cls = method.__self__.__class__
    return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

copyreg.pickle(types.MethodType, _pickle_method, _unpickle_method)

Является ли этот метод надежным для методов травления экземпляров?Или что-то может пойти не так?Я протестировал его с некоторыми классами макетов, и все, кажется, работает.

Если ничего не может пойти не так, почему в Python 3 невозможно использовать стандартные методы экземпляра pickle?

Ответы [ 2 ]

0 голосов
/ 24 сентября 2015

Если вы хотите выбрать экземпляры класса (и методы экземпляров), просто используйте dill ...

>>> import dill
>>> 
>>> class Foo:
...   def bar(self, x):
...     return self.y + x
...   def zap(self, y):
...     self.y = y
...   y = 1
... 
>>> f = Foo()
>>> f.zap(4)
>>> f.monty = 'python'
>>> 
>>> _f = dill.dumps(f)
>>> del Foo
>>> del f
>>> f = dill.loads(_f)
>>> f.monty
'python'
>>> f.y
4
>>> 
>>> _b = dill.dumps(f.bar)
>>> del f
>>> bar = dill.loads(_b)
>>> bar(4)
8
>>> 

dill, когда вы удаляете объект класса, как показано выше… так чтотакже работает, если вы начинаете новый сеанс Python без определенного класса, или если вы изменяете определение класса.dill работает даже тогда, когда у вас нет экземпляра объекта класса или экземпляр класса доступен.Если вы хотите узнать, как это сделать, посмотрите исходный код dill: https://github.com/uqfoundation/dill

См. Также: https://stackoverflow.com/a/21345273/2379433

0 голосов
/ 24 сентября 2015

Я не могу воспроизвести исходную проблему на python 3.5.0, см. Следующий пример.Возможно, стоит проверить последнюю версию, чтобы проверить, работает ли она «из коробки»: -)

import pickle
import sys

class Foo:

    @staticmethod
    def my_func():
        return 'Foo.my_func'


class Bar:
    pass

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'restore':
        print('loading pickle')
        with open('test.pickle', 'rb') as fp:
            restored = pickle.load(fp)
            print(restored.baz())
    else:
        print('saving pickle')
        b = Bar()
        b.baz = Foo.my_func

        with open('test.pickle', 'w+b') as fp:
            p = pickle.dump(b, fp)

(тест) ~ / test $ python test.py

Сохранение сохранения

(тестирование) ~ / test $ python test.py restore

Загрузка загрузки

Foo.my_func

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...