我一直在練習使用 JSON 檔案和 OOP,所以我想我會同時做這兩個,但我一直在努力尋找基于 JSON 部分創建類物件的最有效方法。經過大量詢問后,我發現最好的方法是 using **,即使一個字面上不知道它是如何作業的。代碼是:
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 類物件的最佳方法還是有更好的方法?
uj5u.com熱心網友回復:
使用**運算子可能是首選方法,只要您的建構式引數與您的 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)
在這里,*argsand**kwargs用于捕獲args(arguments) 和kwargs(keyword arguments) 中的位置和關鍵字引數,第二次,它們將它們傳播回對some_other_func. 這些名字并不神奇args,kwargs它們只是約定俗成的。
If you want something a bit less risky (because of the reasons explained above), you could give your class 'to_json' and 'from_json' methods, but fairly soon things will get complicated and you may want to look into existing libraries instead, as user @LeiYang suggests (and there are many of those).
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/443561.html
