Я хотел бы избежать травления определенных полей в экземпляре класса. В настоящее время, прежде чем травить, я просто установил эти поля в None, но мне интересно, есть ли более элегантное решение?
Исключить поле объекта из травления в python
Ответ 1
Существует пример в документации, которая решает вашу проблему с __getstate__
и __setstate__
.
Ответ 2
Один из способов обработки атрибутов экземпляра, которые не являются выбираемыми объектами, - использовать специальные методы, доступные для модификации состояния экземпляра класса: 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() мы можем воссоздать файловый объект на основе информации о имени и позиции, которую мы мариновали, и назначить объект файла атрибуту log файла экземпляра.
Ссылка: http://www.ibm.com/developerworks/library/l-pypers.html
Ответ 3
__getstate__
__setstate__
методы объекта __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