__dict__ 不允许在 Python 中调用方法
Posted
技术标签:
【中文标题】__dict__ 不允许在 Python 中调用方法【英文标题】:__dict__ Doesn't Allow Call to Method in Python 【发布时间】:2016-07-12 20:52:54 【问题描述】:我正在创建一个对象字典,我想保存并在不同时间重新加载(我想使用“json”模块,而不是“pickle”)。
我创建了一个类(我们称它为“Ball”),而字典只包含该类的许多不同实例。它的样子是:
my_dict =
"ball1": "size": "big", "baseball": False, etc...,
"ball2": "size": "small", "baseball": True, etc...,
etc...
当我创建“Ball”类的新实例时,我只是将它们附加到“my_dict”。
我的“Ball”类具有允许我更改某些字段值的方法...即:
changeSize(self, size)
问题:
为了让我的保存功能能够正常使用 json 模块,我必须对“Ball”类的每个新实例执行以下操作:
newBall = Ball(name)
my_dict[name] = newBall.__dict__
添加
.__dict__
然后将其附加到字典使其 JSON 可序列化,但它使当我进入“编辑模式”时我无法调用该方法(即 changeSize(name) ),因为它只是一个字典不再是“球”对象。
如何制作以便我可以保存(使用 json 模块)并使用我现有的方法进行编辑?
另外,我保存/加载的方式如下:
out_file = open("testSave.json"), "w")
json.dump(my_dict, out_file, indent=4)
out_file.close()
in_file = open("testSave.json", "r")
my_dict = json.load(in_file)
in_file.close()
谢谢!
【问题讨论】:
【参考方案1】:最终,json
不支持序列化任意 python 对象。如果你想这样做,你可以看看pickle
。
或者,您可以在 Ball
上创建一个备用构造函数,该构造函数将使用来自 dict
的值对其进行初始化:
class Ball(object):
@classmethod
def from_json(self, dictionary):
b = cls()
b.__dict__.update(dictionary)
return b
...
我写这个假设Ball
构造函数可以用0
参数调用——如果不是这样,或者__init__
做了任何“花哨”的事情,你可能需要修改代码(除了设置json
可序列化属性)。解决__init__
参数要求的一种方法是使用__new__
创建实例,然后通过更新类字典来填充成员:
class Ball(object):
def __init__(self, name, foo, bar):
self.name = name
self.foo = foo
self.bar = bar
def to_dict(self):
return self.__dict__
@classmethod
def from_dict(cls, dictionary):
self = cls.__new__(cls)
self.__dict__.update(dictionary)
return self
def __str__(self):
return 'Ball(%r, %r, %r)' % (self.name, self.foo, self.bar)
b = Ball('HockyPuck', 'flat', 'NotABall')
d = b.to_dict()
bb = Ball.from_dict(d)
print(bb)
这适用于 python2.x 和 3.x。
【讨论】:
Ball
构造函数至少需要一个名称(但它会在程序中提示,因此保证会发生)。你是说如果我基本上做了与pickle
相同的事情,它会起作用吗?我知道它不太安全,这就是我尝试学习 json 方式的原因。另外,如果我继续使用json
,您能否快速解释一下您为什么使用decorator
?我对他们不是很了解。非常感谢!
@AmericanMade -- 你也可以使用b = cls(dictionary.get('name'))
或类似的方法。回复:pickle
——那里肯定存在安全问题。如果你不完全信任它,就永远不要解开它。至于@classmethod
,这只是使得from_json
、cls
中的@是类而不是类的实例。以上是关于__dict__ 不允许在 Python 中调用方法的主要内容,如果未能解决你的问题,请参考以下文章