首先第一件事,不只是raise Exception
;這太籠統了,儘可能詳細地描述出了什麼問題。在這種情況下,用戶沒有提供info
參數。兩個問題是:
你應該通過身份測試None
,不感實性(否則例如{}
將是一個例外,這可能不是你真正想要的東西):if info is not None:
。
如果這是一個必需的參數,爲什麼給它一個默認值?
修訂1:
import json
class LoadInfo(object):
def __init__(self, info):
try:
self.config = json.loads(info)
except ValueError:
print('Load Python Dict')
try:
if isinstance(info, dict):
self.config = info
except ValueError:
print('python dict config is needed')
(注輕微style guide調整。)
接下來,真的沒有必要通過允許提供這種多態性無論是字典或JSON字符串作爲參數。在第二種情況下,您只是將它解析爲第一種情況,那麼請創建一個類方法,這是Python中常見的替代構造函數模式。
修訂2:
import json
class LoadInfo(object):
def __init__(self, info):
try:
if isinstance(info, dict):
self.config = info
except ValueError:
print('python dict config is needed')
@classmethod
def from_json(cls, info):
return cls(json.loads(info))
其中的一部分:
if isinstance(info, dict):
self.config = info
你希望提出一個ValueError
?爲什麼呢,如果它不是一種可以接受的輸入類型,你想只是print
的東西,讓程序繼續?請注意,如果您正在檢查類型,最好使用ABCs。
修訂3:
from collections.abc import Mapping
import json
class LoadInfo(object):
def __init__(self, info):
if not isinstance(info, Mapping):
raise TypeError('mapping config is needed')
self.config = info
@classmethod
def from_json(cls, info):
return cls(json.loads(info))
但實際上,你所建議的,它可以從一個文件,而不是JSON字符串作爲當前的代碼加載意味着(你提供'path/to/json_file'
不'{"foo": "bar"}'
- 這不是清楚你所期望的json.loads
)。所以你需要處理該文件。
修訂4:
from collections.abc import Mapping
import json
class LoadInfo(object):
def __init__(self, info):
if not isinstance(info, Mapping):
raise TypeError('mapping config is needed')
self.config = info
@classmethod
def from_json_file(cls, filename):
with open(filename) as json_file:
return cls(json.load(json_file)) # note 'load' not 'loads'
現在你的例子變成:
info = LoadInfo.from_json_file('path/to/json_file')
info_dict = dict(A=1, B=2, C=3) # note you shouldn't use quotes for keys here
info2 = LoadInfo(info_dict)
IMO你應該調整你的代碼。爲什麼不能簡單地將數據加載到'LoadInfo'類之外並將結果傳遞給它?爲什麼'LoadInfo'應該在一個參數下接受兩種不同的類型? – freakish
爲什麼要編寫一個需要字典或JSON字符串的代碼?我會寫一個classmethod'def from_json(cls,info):return cls(json.loads(info))'。這樣你只能處理'__init__'中的字典案例。你也不應該只是'拋出異常:';如果需要'info'參數,*不要給它一個默認值*。 – jonrsharpe