Исключить поле объекта из травления в питоне - PullRequest
21 голосов
/ 27 февраля 2010

Я бы хотел избежать травления определенных полей в экземпляре класса. В настоящее время, перед засолкой, я просто установил для этих полей значение Нет, но мне интересно, есть ли более элегантное решение?

Ответы [ 3 ]

30 голосов
/ 27 февраля 2010

Один из способов обработки атрибутов экземпляра, которые не являются объектами для выбора, состоит в использовании специальных методов, доступных для изменения состояния экземпляра класса: getstate () и setstate (). Вот пример

class Foo(object):

    def __init__(self, value, filename):
        self.value = value
        self.logfile = file(filename, 'w')

    def __getstate__(self):
        """Return state values to be pickled."""
        f = self.logfile
        return (self.value, f.name, f.tell())

    def __setstate__(self, state):
        """Restore state from the unpickled state values."""
        self.value, name, position = state
        f = file(name, 'w')
        f.seek(position)
        self.logfile = f

Когда экземпляр Foo выбирается, Python выбирает только те значения, которые ему возвращаются, когда он вызывает метод экземпляра getstate (). Точно так же, во время расщепления, Python предоставит несортированные значения в качестве аргумента для метода setstate () экземпляра. Внутри метода setstate () мы можем воссоздать файловый объект на основе выбранной нами информации об имени и позиции и назначить объект файла атрибуту logfile экземпляра.

Ссылка: http://www.ibm.com/developerworks/library/l-pypers.html

8 голосов
/ 27 февраля 2010
4 голосов
/ 11 января 2019

Пиклинг использует методы объекта __getstate__ и __setstate__; Вы можете переопределить их и игнорировать нужные поля.

# foo.py
class Foo:
    def __init__(self):
        self.bar = 1
        self.baz = 2

    def __getstate__(self):
        state = self.__dict__.copy()
        # Don't pickle baz
        del state["baz"]
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        # Add baz back since it doesn't exist in the pickle
        self.baz = 0
# main.py
import pickle

from foo import Foo


foo = Foo()
print(f"Foo bar: {foo.bar} baz: {foo.baz}")

new_foo = pickle.loads(pickle.dumps(foo))
print(f"New bar: {new_foo.bar} baz: {new_foo.baz}")

Выход:

Foo bar: 1 baz: 2
New bar: 1 baz: 0

Вы можете найти другой пример здесь: https://docs.python.org/3/library/pickle.html#handling-stateful-objects

...