Issue
This Content is from Stack Overflow. Question asked by Rubia
We have sample Python dictionary as given below, which can be modify by multiple developers in our project.
What could be best way to avoid developers not to add other than given sample keys, also to avoid them to add incorrect zip entry in address of person( zip should validate through post codes then allow to add zip), etc. I think we can do it with special functions dict.add dict.key is there any other best way to do it.
people = {1: {'name': 'John', 'age': '27', 'sex': 'Male', 'Address': { 'Door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip':'99705'}},
2: {'name': 'Marie', 'age': '22', 'sex': 'Female', 'Address': { 'Door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip': '99705'}}}
Eg of bad entry:
{1: {'name12': 'John', 'age': '27', 'sex': 'Male', 'Address': { 'Door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip':'000000'}}
Solution
One approach that you might want to consider is creating your own class for each of the people for which the "given sample keys" (e.g. name, age, sex, and address) are object attributes and keyword arguments to the initialization function. For instance, you could do the following.
class Person(object):
def __init__(self, name = '', age = '0', sex = None, address = {}):
self.name = name
self.age = age
self.sex = sex
self.address = address
With that, you can enter person one into the system with
person_1 = Person(name = 'John',
age = '27',
sex = 'Male',
address = { 'Door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip':'99705'})
In fact, you can very nicely unpack your dictionary version of a person to create this a Person
instance. For example, we can change your dictionary of dictionaries to a dictionary of Person
objects as follows.
people_dic_1 = {1: {'name': 'John', 'age': '27', 'sex': 'Male', 'address': { 'door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip':'99705'}},
2: {'name': 'Marie', 'age': '22', 'sex': 'Female', 'address': { 'door': '9-8-11', 'street': 'John-street', 'city': 'NewYork', 'zip': '99705'}}}
people_dic_2 = {k:Person(**v) for k,v in people_dic.items()}
In the above, Person(**v)
is a person object with attributes determined by the dictionary v
. Notably, calling Person(**v)
will only work if each key corresponds to a (correctly named) keyword argument of the __init__
method.
To go the other direction, you can call vars
on a Person
object to produce the kind of dictionary that you’ve been using. For instance, calling vars(people_dic_2[2])
after running the above code yields the dictionary
{'name': 'Marie',
'age': '22',
'sex': 'Female',
'address': {'door': '9-8-11',
'street': 'John-street',
'city': 'NewYork',
'zip': '99705'}}
You could similarly create a class for addresses, if you’re so inclined.
This Question was asked in StackOverflow by Rubia and Answered by Ben Grossmann It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.