First things first, don't just raise Exception; that's far too general, be as specific as you can about what has gone wrong. In this case, it's that the user hasn't provided the info parameter. Two problems with that:
You should test for None by identity, not truthiness (otherwise e.g. {} would be an exception, which may not be what you actually want): if info is not None:.
If it's a required parameter, why give it a default value?!
Revision 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')
(Note minor style guide tweaks.)
Next, there's really no need to provide this kind of polymorphism by allowing either a dictionary or a JSON string as the argument. As in the second case you're just parsing it to the first case, make that a class method, which is the common alternate constructor pattern in Python.
Revision 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))
Which part of:
if isinstance(info, dict):
self.config = info
do you expect to raise a ValueError? And why, in the case where it's not an acceptable type of input, would you want to just print something and let the program continue? Note that where you're checking types, it's better to use the ABCs.
Revision 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))
But actually, you're suggesting that it be loaded from a file, not the JSON string as your current code implies (you provide 'path/to/json_file' not '{"foo": "bar"}' - it's not clear what you expected json.loads to make of that). So you need to handle that file.
Revision 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'
Now your examples become:
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)
LoadInfoclass and pass the result to it? WhyLoadInfoshould accept two different types under one param?def from_json(cls, info): return cls(json.loads(info)). That way you only deal with the dictionary case in__init__. Also you should never justraise Exception:; if theinfoparameter is required, don't give it a default value.