使用 JSON 在 Python 中创建类对象的最佳方法
原文标题 :Best way to use a JSON to create class objects in Python
我一直在练习使用 JSON 文件和 OOP,所以我想我会同时做这两个,但我一直在努力寻找基于 JSON 部分创建类对象的最有效方法。经过大量询问后,我发现最好的方法是使用**
,即使一个字面上不知道它是如何工作的。代码是:
import json
class Warship(object):
def __init__(self, name, gun_config, top_speed, belt_armor, displacement):
self.name = name
self.gun_config = gun_config
self.top_speed = top_speed
self.belt_armor =belt_armor
self.displacement = displacement
def __repr__(self):
return f'''{self.name}, {self.gun_config}, {self.top_speed} knts, {self.belt_armor} mm, {self.displacement} tons'''
workfile = json.load(open('warships.json', 'r'))
bisc = Warship(**workfile['kms'][0])
tirp = Warship(**workfile['kms'][1])
nc = Warship(**workfile['usn'][0])
wa = Warship(**workfile['usn'][1])
这是我为这个练习制作的 JSON 文件:
{
"kms": [
{
"name": "Bismarck",
"gun_config": "3x2",
"top_speed": "29",
"belt_armor": "320",
"displacement": "41700"
},
{
"name": "Tirpitz",
"gun_config": "3x2",
"top_speed": "30",
"belt_armor": "320",
"displacement": "41700"
}
],
"usn": [
{
"name": "North Carolina",
"gun_config": "3x3",
"top_speed": "28",
"belt_armor": "305",
"displacement": "36600"
},
{
"name": "Washington",
"gun_config": "3x3",
"top_speed": "29",
"belt_armor": "305",
"displacement": "36600"
}
]
}
使用 **
这样的方式是基于 JSON 对象创建 Python 类对象的最佳方式还是有更好的方式?
回复
我来回复-
Grismar 评论
使用
**
操作符可能是首选的方法,只要您的构造函数参数与您的 JSON 属性的名称完全匹配(就像它们在您的示例中所做的那样)并且只要构造函数上没有可能造成严重破坏的其他参数:def Message: def __init__(greeting: str, wipe_c_drive: bool = False): self.greeting = greeting if wipe_c_drive: shutil.rmtree('C:/') workfile = json.load(open('greetings.json', 'r')) hello = Message(**workfile['hello'])
greetings.json
中的数据:{ "hello": { "greeting": "Hello there!" } }
有什么可能出错的,对吧?
**
操作符是一个“传播”操作符,它像字典一样接受一个键/值对数据对象,并传播它——通常为函数提供关键字参数:def say(greeting, name): print(f'{greeting} to you, {name}!') d = {'greeting': 'hello', 'name': 'AnFa') say(**d)
这也适用于您的情况,因为 JSON 对象作为字典加载,因此可以使用
**
运算符进行传播。由于 JSON 对象的属性与构造函数的关键字参数名称完全匹配,因此它可以工作。类似地,
*
运算符展开一个列表:xs = ['hello', 'AnFa'] say(*xs)
这具有相同的结果,但尝试将值作为位置参数传递。
了解了以上内容,你可能也明白为什么有时会看到这个:
def some_func(x, *args, **kwargs): print(x) some_other_func(*args, **kwargs)
在这里,
*args
和**kwargs
在args
(参数)和kwargs
(关键字参数)中捕获位置和关键字参数,第二次,它们将它们传播回对some_other_func
的调用。那些名字args
和kwargs
并不神奇,它们只是约定俗成的。如果您想要一些风险较小的东西(由于上述原因),您可以为您的类提供 ‘to_json’ 和 ‘from_json’ 方法,但很快事情就会变得复杂,您可能想要查看现有的库,因为用户@LeiYang 建议(其中有很多)。
2年前