[系統互動篇] 如何將物件序列化 (將物件儲存到檔案) - tsungjung411/python-study GitHub Wiki
numpy.NaN 不能序列化,物件位址不一樣
注意:numpy.NaN
地雷
import numpy
my_dict = {'A':1, 'B':2, 'C':numpy.NaN, 'D': None, numpy.NaN:3, None: 4}
print('C:', my_dict.get('C'))
print(' - == numpy.NaN:', my_dict.get('C') == numpy.NaN)
print(' - is numpy.NaN:', my_dict.get('C') is numpy.NaN, '<---')
print(' - numpy.isnan():', numpy.isnan(my_dict.get('C')))
print(' - hash():', hash(my_dict.get('C')))
print('D:', my_dict.get('D'))
print(' - == None:', my_dict.get('D') == None)
print(' - is None:', my_dict.get('D') is None)
print(' - hash():', hash(my_dict.get('D')))
print('numpy.NaN:', my_dict.get(numpy.NaN), '<---')
print('None:', my_dict.get(None))
import pickle
with open('my_dict.pkl', 'wb') as f:
pickle.dump(my_dict, f)
with open('my_dict.pkl', 'rb') as f:
my_dict = pickle.load(f)
print('C:', my_dict.get('C'))
print(' - == numpy.NaN:', my_dict.get('C') == numpy.NaN)
print(' - is numpy.NaN:', my_dict.get('C') is numpy.NaN, '<---')
print(' - numpy.isnan():', numpy.isnan(my_dict.get('C')))
print(' - hash():', hash(my_dict.get('C')))
print('D:', my_dict.get('D'))
print(' - == None:', my_dict.get('D') == None)
print(' - is None:', my_dict.get('D') is None)
print(' - hash():', hash(my_dict.get('D')))
print('numpy.NaN:', my_dict.get(numpy.NaN), '<---')
print('None:', my_dict.get(None))
測試結果1:未經過序列化
測試結果2:經過序列化
A.pwd, A._pwd, A.__pwd, A.pwd 做序列化
import pickle
class A:
def __init__(self):
self.name = 'TJ'
self.age = 25
self.pwd = '12'
self._pwd = '34'
self.__pwd = '56'
self.__pwd__ = '78'
def __repr__(self):
return '{name: %s, age: %d, pwd: %s, _pwd: %s, __pwd: %s, __pwd__: %s}' % (
self.name if hasattr(self, 'name') else None,
self.age if hasattr(self, 'age') else 0,
self.pwd if hasattr(self, 'pwd') else None,
self._pwd if hasattr(self, '_pwd') else None,
self.__pwd if hasattr(self, '_' + self.__class__.__name__ + '__pwd') else None,
self.__pwd__ if hasattr(self, '__pwd__') else None,
)
def __getstate__(self):
print('serailizing...')
state = dict((k, v)
for k, v in self.__dict__.items()
if self.should_pickle(k))
print('state:', state)
return state
def hello(self):
pass
def should_pickle(self, attr):
route = 3
if route == 3: # __attr:
return True # attr
elif route == 2: # __attr
return not attr.startswith('_' + self.__class__.__name__) \
and not attr.startswith('__')
elif route == 1: # _attr
return not attr.startswith('_')
else:
return False
a = A()
print('a:', a)
print('a.__dict__:', a.__dict__)
with open('a.pkl', 'wb') as f:
pickle.dump(a, f)
執行結果:
a: {name: TJ, age: 25, pwd: 12, _pwd: 34, __pwd: 56, __pwd__: 78}
a.__dict__: {'name': 'TJ', 'age': 25, 'pwd': '12', '_pwd': '34', '_A__pwd': '56', '__pwd__': '78'}
serailizing...
state: {'name': 'TJ', 'age': 25, 'pwd': '12', '_pwd': '34', '_A__pwd': '56', '__pwd__': '78'}
a = None
with open('a.pkl', 'rb') as f:
a = pickle.load(f)
try:
print('a.name:', a.name)
except AttributeError:
print("[AttributeError] has no attribute 'name'")
try:
print('a.age:', a.age)
except AttributeError:
print("[AttributeError] has no attribute 'age'")
try:
print('a._pwd:', a._pwd)
except AttributeError:
print("[AttributeError] has no attribute '_pwd'")
try:
print('a.__pwd:', a.__pwd) # always failed (not allowed)
except AttributeError:
print("[AttributeError] has no attribute '__pwd'")
try:
print('a.__pwd__:', a.__pwd__)
except AttributeError:
print("[AttributeError] has no attribute '__pwd__'")
執行結果:
a.name: TJ
a.age: 25
a._pwd: 34
[AttributeError] has no attribute '__pwd'
a.__pwd__: 78