上一篇记录pickle基本操作,这一篇学习研究那些类型是可以pickle的。引用
Python’s pickle (I’m talking standard Python 2.5/2.6/2.7 here) cannot pickle locks, file objects etc.
It also cannot pickle generators and lambda expressions (or any other anonymous code), because the pickle really only stores name references.
Python的pickle(我在这里说的标准Python 2.5 / 2.6 / 2.7)不能pickle lock、file对象等。
它也不能pickle生成器和lambda表达式(或任何其他匿名代码),因为pickle只存储名称引用。
pickle只存储名称引用怎么理解。我写了下面的测试代码。这里我在同一目录编写两个文件,一个用来存储,一个用来读取。
测试1目标测试函数,普通函数和带有生成器(yield语句)的函数
测试在一个文件读
# coding: utf8
import pickle
import pickle
def storeTree(filename,*args):
with open(filename,'wb') as fw: #打开需要用'wb'
for i in args:
pickle.dump(i, fw,-1) #为了保护数据protocol=-1,设为0可以看到数据
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
def TextPick(s,j):
return("{}:{}".format(s,j))
def Tyield(i=None):
if i is None:
i=2
while 1:
yield i
i+=1
if __name__ == "__main__":
filename = "pickT.txt" #测试函数
n = Tyield().__next__()
# n=Tyield() #执行这句出现错误
# can't pickle generator objects 执行这句不能pickle generator对象
storeTree(filename,TextPick,n) #这里n存储的是一个整数
s=grabTree(filename)
print("返回第一个是函数结果={}".format(s[0](2,3)))
print("返回第二个是函数类型={}".format(type(s[1])))
print("返回第二个是函数结果={}".format(s[1]))
输出:
返回第一个是函数结果=2:3
返回第二个是函数类型=<class ‘int’>
返回第二个是函数结果=2
第一个返回函数对象,第二个返回int对象执行完这个程序后我们看看其他程序调用
# coding: utf8
import pickle
import pickle
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
def TextPick(s,j):
return ("{}:{}".format(s, j))
if __name__ == "__main__":
filename = "pickT.txt"
b1=grabTree(filename)[0]
print("返回第调函数{}".format(b1))
print("返回第调函数调用b1(2,3){}".format(b1(2,3)))
输出:
返回第调函数<function TextPick at 0x01958078>
返回第调函数调用b1(2,3)2:3
这和我们的预期是一致的。不由考虑,如果读取程序没有定义TextPick怎摸样 现在修改代码将TextPick改个名。运行
出现错误
File "D:/PYthonPro/CSV解析/量化序列化读取.py", line 22, in <module>
b1=grabTree(filename)[0]
IndexError: list index out of range
list index out of 应该是查找没有找到函数名越界了。
其次如果我们修改函数内容会怎么样
将TextPick改为看看运行结果
def TextPick(s,j):
return s+j
返回第调函数<function TextPick at 0x01938078>
返回第调函数调用b1(2,3)5
所以得出结论pickle保存函数实际上保存的函数名
讨论完函数再讨论一下类,调用类名和函数是相似的,两个程序必须有相同的类名,因为类有内部变量,所以需要测试一下
# coding: utf8
import pickle
import pickle
def storeTree(filename,*args):
with open(filename,'wb') as fw: #打开需要用'wb'
for i in args:
pickle.dump(i, fw,-1) #为了保护数据protocol=-1,设为0可以看到数据
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
class Person:
def __init__(self,n,a):
self.name=n
self.age=a
def show(self):
print("name={},age={}".format(self.name,self.age))
if __name__ == "__main__":
filename = "pickT.txt" #测试类和函数
_P=Person
aa = Person("JGood", 2)
print("第一次实例")
aa.show()
storeTree(filename,aa,_P)
s=grabTree(filename)
b0=s[0]
print("第二次实例")
b0.show()
b1 = s[1]
b1实例=b1("赵虎",12)
print("b1实例实例")
b1实例.show()
输出:
第一次实例
name=JGood,age=2
第二次实例
name=JGood,age=2
b1实例实例
name=赵虎,age=12
我们在另一个文件读取一下存储的数据
# coding: utf8
import pickle
import pickle
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
class Person:
def __init__(self,n,a):
self.name=n
self.age=a
def show(self):
print("name={},age={}".format(self.name,self.age))
if __name__ == "__main__":
filename = "pickT.txt"
s = grabTree(filename)
b0 = s[0]
print("第二次实例")
b0.show()
b1 = s[1]
b1实例 = b1("赵虎", 12)
print("b1实例实例")
b1实例.show()
输出:
第二次实例
name=JGood,age=2 看到内部变量保留了
b1实例实例
name=赵虎,age=12
# coding: utf8
import pickle
import pickle
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
class Person:
def __init__(self,n,a):
self.name=n
self.age=a
self.oth="name={},age={}".format(self.name,self.age) #增加一个变量
def show(self):
print("name={},age={}".format(self.name,self.age))
if __name__ == "__main__":
filename = "pickT.txt"
s = grabTree(filename)
b0 = s[0]
print("b0的内部变量{}".format(b0.__dict__))
print("第二次实例")
b0.show()
b1 = s[1]
b1实例 = b1("赵虎", 12)
print(print("b1实例的内部变量{}".format(b1实例.__dict__)))
print("b1实例实例")
b1实例.show()
输出:
b0的内部变量{‘name’: ‘JGood’, ‘age’: 2} 这里有两个变量
第二次实例
name=JGood,age=2
b1实例的内部变量{‘name’: ‘赵虎’, ‘age’: 12, ‘oth’: ‘name=赵虎,age=12’}
这里有3个变量
None
b1实例实例
name=赵虎,age=12
从这里可以看出 pickle只存储名称引用的含义