从YAML加载序列化对象并替换当前对象

3 投票
1 回答
1250 浏览
提问于 2025-04-16 19:59

我遇到了一个我原本以为很常见的问题,但我找不到解决办法。

我在Python中有一个类,这个类里有一些实例变量,用来存储模型的参数。我给这个类添加了两个方法:

def save_params(self, filename):
    f = open(filename, "w")
    yaml.dump(self, f, default_flow_style=False)
    f.close()

def load_params(self, filename):
    f = open(filename, "r")
    obj = yaml.load(f)
    print obj.aero_soot
    self = copy.deepcopy(obj)
    f.close()

我想用这两个方法把这个对象的属性值保存到一个YAML文件中,然后再从YAML文件中加载回来。

save_params方法运行得很好,但load_params方法却不行。它可以从YAML文件中正确加载数据到obj里,但obj中的属性在当前对象实例(self)中没有被正确设置。

我可能在这里做了什么傻事,但到底是什么呢?

1 个回答

1

问题出在你对 self 的赋值上,这里有个很好的解释 在这里。简单来说,在函数内部,self 是一个局部变量,所以把它绑定到其他值上并不会影响函数外的内容。

为了绕过这个问题,你可以试试用 self.__dict__ = obj.__dict__。不过,这种方法只有在你没有对当前对象的 __dict__ 进行任何修改的情况下才有效。

不过,我建议你换个方法:把加载和保存的函数做成普通函数或者类方法,这样可以返回对象:

@classmethod
def save_params(cls, obj, filename):
    with open(filename, "w") as f:
        yaml.dump(obj, f, default_flow_style=False)

@classmethod   
def load_params(cls, obj, filename):
    with open(filename, "r") as f:
        obj = yaml.load(f)
        print obj.aero_soot
        return obj

撰写回答