我在Python中使用Email()类,我希望将其扩展到SerializeEmail()类,它只是添加了两个方法,.write_email()和.read_email()。我想要这种行为:
# define email
my_email = SerializeEmail()
my_email.recipients = 'link@hyrule.com'
my_email.subject = 'RE: Master sword'
my_email.body = "Master using it and you can have this."
# write email to file system for hand inspection
my_email.write_email('my_email.txt')
...
# Another script reads in email
my_verified_email = SerializeEmail()
my_verified_email.read_email('my_email.txt')
my_verified_email.send()
我已经导航了json编码/解码过程,我可以成功编写我的SerializeEmail()对象并读取它,但是,我找不到一种令人满意的方法来通过SerializeEmail.read_email()重新创建我的对象调用
class SerializeEmail(Email):
def write_email(self,file_name):
with open(file_name,"w") as f:
json.dump(self,f,cls=SerializeEmailJSONEncoder,sort_keys=True,indent=4)
def read_email(self,file_name):
with open(file_name,"r") as f:
json.load(f,cls=SerializeEmailJSONDecoder)
这里的问题是我的read_email()方法中的json.load()调用返回了我的SerializeEmail对象的实例,但没有将该对象分配给我用来调用它的当前实例。所以现在我必须做这样的事情,
another_email = my_verified_email.read_email('my_email.txt')
当我想要的是调用my_veridied_email.read_email()以使用文件上的数据填充my_verified_email的当前实例。我试过了
self = json.load(f,cls=SerializeEmailJSONDecoder)
但这不起作用。我可以将我返回的对象的每个单独元素分配给我的“自我”对象,但这似乎是临时的和不优雅的,我正在寻找“正确的方法”来做到这一点,如果它存在的话。有什么建议?如果您认为我的整个方法存在缺陷并建议采用不同的方式来完成此任务,请为我绘制草图。
答案 0 :(得分:2)
虽然您可以通过一些箍来将序列化内容加载到现有实例中,但我不建议这样做。这是一种不必要的并发症,它真的让你没有任何好处;这意味着每次要从JSON加载电子邮件时都需要创建虚拟实例的额外步骤。我建议使用工厂类或工厂方法,它从序列化的JSON加载电子邮件并将其作为新实例返回。我个人的偏好是工厂方法,你可以按如下方式完成:
class SerializeEmail(Email):
def write_email(self,file_name):
with open(file_name,"w") as f:
json.dump(self,f,cls=SerializeEmailJSONEncoder,sort_keys=True,indent=4)
@staticmethod
def read_email(file_name):
with open(file_name,"r") as f:
return json.load(f,cls=SerializeEmailJSONDecoder)
# You can now create a new instance by simply doing the following:
new_email = SerializeEmail.read_email('my_email.txt')
注意@staticmethod装饰器,它允许你在类上调用方法而不传入任何隐式的第一个参数。通常工厂方法是@classmethod s,但是因为你正在加载来自JSON的对象,隐式类参数是不必要的。
请注意,通过此修改,您无需在从JSON加载另一个对象之前实例化SerializeEmail
对象。您只需直接在类上调用该方法并获得所需的行为。