python 复合对象的序列化
python serialization of composite object
我有以下代码片段:
import pickle
class Date:
def __init__(self, d=1, m=1, y=1):
self.Day = d
self.Month = m
self.Year = y
def __str__(self):
return str(self.Day) + "-" + str(self.Month) + "-" + str(self.Year)
class Person:
def __init__(self, n=0,dob=Date(0,0,0)):
self.no = n
self.DOB = dob
def __str__(self):
return "No = " + str(self.no) + ", DOB = " + str(self.DOB)
#main
f = open("a.dat", "wb")
d=dict()
p=Person()
p.no = int(raw_input("Enter empl no: "))
p.DOB.Day = int(raw_input("Enter day: "))
p.DOB.Month = int(raw_input("Enter Month: "))
p.DOB.Year = int(raw_input("Enter Year: "))
d[p.no] = p
p=Person()
p.no = int(raw_input("Enter empl no: "))
p.DOB.Day = int(raw_input("Enter day: "))
p.DOB.Month = int(raw_input("Enter Month: "))
p.DOB.Year = int(raw_input("Enter Year: "))
d[p.no] = p
pickle.dump(d,f)
f.close()
#now open the file again
f = open("a.dat", "rb")
d = pickle.load(f)
for p in d.values():
print str(p)
我有两个人存储在字典中,序列化后保存在文件中。两个人都有不同的 DOB,但是从文件加载回来时,它显示相同的 DOB。
输入输出如下:
Enter empl no: 1
Enter day: 1
Enter Month: 1
Enter Year: 2001
Enter empl no: 2
Enter day: 2
Enter Month: 2
Enter Year: 2002
No = 1, DOB = 2-2-2002
No = 2, DOB = 2-2-2002
这里有什么问题?为什么日期显示相同,尽管两个对象的日期不同。
请建议。
有一些关于 “Least Astonishment” in Python: The Mutable Default Argument 的讨论,但是如果我想为不同的 Person 对象输入不同的日期怎么办?
问题出在使用默认对象参数初始化时:
def __init__(self, n=0,dob=Date(0,0,0)):
正如您将在 this 讨论中看到的那样,Date
构造函数不会在您对方法进行的每次调用中调用。相反,它在第一次加载模块时调用一次,然后始终使用同一个实例。你假设你有不同的 DOB 是错误的。
编辑:如果您仍想保留默认参数行为,处理此类情况的常见范例是分配 None
并检查它是否已初始化。在您的情况下,这意味着:
def __init__(self, n=0,dob=None):
# By calling `Date` in the initialiser's body, it's guaranteed to generate a new instance for every call
if dob is None:
dob = Date(0,0,0)
# At this point self.DOB is initialised with either a new instance or a given one
self.DOB = dob
我有以下代码片段:
import pickle
class Date:
def __init__(self, d=1, m=1, y=1):
self.Day = d
self.Month = m
self.Year = y
def __str__(self):
return str(self.Day) + "-" + str(self.Month) + "-" + str(self.Year)
class Person:
def __init__(self, n=0,dob=Date(0,0,0)):
self.no = n
self.DOB = dob
def __str__(self):
return "No = " + str(self.no) + ", DOB = " + str(self.DOB)
#main
f = open("a.dat", "wb")
d=dict()
p=Person()
p.no = int(raw_input("Enter empl no: "))
p.DOB.Day = int(raw_input("Enter day: "))
p.DOB.Month = int(raw_input("Enter Month: "))
p.DOB.Year = int(raw_input("Enter Year: "))
d[p.no] = p
p=Person()
p.no = int(raw_input("Enter empl no: "))
p.DOB.Day = int(raw_input("Enter day: "))
p.DOB.Month = int(raw_input("Enter Month: "))
p.DOB.Year = int(raw_input("Enter Year: "))
d[p.no] = p
pickle.dump(d,f)
f.close()
#now open the file again
f = open("a.dat", "rb")
d = pickle.load(f)
for p in d.values():
print str(p)
我有两个人存储在字典中,序列化后保存在文件中。两个人都有不同的 DOB,但是从文件加载回来时,它显示相同的 DOB。 输入输出如下:
Enter empl no: 1
Enter day: 1
Enter Month: 1
Enter Year: 2001
Enter empl no: 2
Enter day: 2
Enter Month: 2
Enter Year: 2002
No = 1, DOB = 2-2-2002
No = 2, DOB = 2-2-2002
这里有什么问题?为什么日期显示相同,尽管两个对象的日期不同。 请建议。 有一些关于 “Least Astonishment” in Python: The Mutable Default Argument 的讨论,但是如果我想为不同的 Person 对象输入不同的日期怎么办?
问题出在使用默认对象参数初始化时:
def __init__(self, n=0,dob=Date(0,0,0)):
正如您将在 this 讨论中看到的那样,Date
构造函数不会在您对方法进行的每次调用中调用。相反,它在第一次加载模块时调用一次,然后始终使用同一个实例。你假设你有不同的 DOB 是错误的。
编辑:如果您仍想保留默认参数行为,处理此类情况的常见范例是分配 None
并检查它是否已初始化。在您的情况下,这意味着:
def __init__(self, n=0,dob=None):
# By calling `Date` in the initialiser's body, it's guaranteed to generate a new instance for every call
if dob is None:
dob = Date(0,0,0)
# At this point self.DOB is initialised with either a new instance or a given one
self.DOB = dob