[SOLVED] Restrict adding bad entry to python dictionary?

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.

people found this article helpful. What about you?