I have a class with a constructor that receives several arguments. These arguments I get from an external file, which is a list of dictionaries.
My problem is that some dictionaries have missing fields. If a field is missing, I want the constructor to simply receive None instead. But as the code is written now, it exits on an exception.
This is a simple illustration of the situation
class Person() def __init__(self, id, age, name, gender): self.id = id self.age = age self.name = name self.gender = gender people_list = pickle.load(open("some_file.p", "rb")) first_person = people_list[0] # this is a dictionary {'id': '1234', 'age': 27, 'name': 'robert'} Person(first_person['id'], first_person['age'], first_person['name'], first_person['gender'])
As the code is written right now, I get an exception that 'gender'
does not exist as a key in the dictionary, which is true. I want any missing field to gets passed a None
value, but without doing a billion if
s or try .. except
s. Is there a good way to do this? Obviously without still incurring an exception.
Advertisement
Answer
In general, you can get a value from a dict
with a default if it doesn’t exist with:
d = {'a': 1} print(d.get('b')) # prints None
But in your case, this would be more appropriate:
class Person(): # the defaults are defined in the constructor def __init__(self, id, age=None, name=None, gender=None): self.id = id self.age = age self.name = name self.gender = gender people_list = pickle.load(open("some_file.p", "rb")) for person in people_list: Person(**person) # assuming they at least all have an 'id'
Of course, this only works if the keys of the dictionaries match the names of the parameters exactly.
The **
operator ‘unpacks’ the dictionary, so this:
d = {'a': 1, 'b': 2} f(**d)
Is the same as:
f(a=1, b=2)