1

Suppose I have the code below:

class Person(object):
""" Capture user demographics data"""

def __init__(self, name, address, phone, gender, name_prefix):
    """ Initialize the object """
    self.name = name
    self.address = address
    self.phone = phone
    self.gender = gender
    self.prefix = name_prefix


def display_userdata(self):
    """ Returns user data"""
    userdata = {'name':self.name, 'address': self.address, 
                'phone': self.phone, 'gender': self.gender, 'prefix': self.prefix
               }
    return userdata

I can initialize the data:

newperson = Person("Ben", '9999 Gotham City, las vegas', '702-000-0000', 'male', 'Waiter')

But I have a feeling that the display_userdata() function is redundant if I could re-write __init to store as dict.

newperson.display_userdata()

It returns the output:

{'address': '9999 Gotham City, las vegas',
 'gender': 'male',
 'name': 'Ben',
 'phone': '702-000-0000',
 'prefix': 'Waiter'}

My questions are:

Is there a smarter way to write the __init__ snippet so the input is stored directly as python dictionary? I don't want to call the constructor with dict key by using setattr.

Secondly, Suppose the user has 3 phones or more (variable), how do I store this in an array while calling the object constructor. Think self.phone = ['702-000-000', '413-222-3333' ]

3 Answers 3

2

Why not just create the dict directly in the init?

class Person(object):
""" Capture user demographics data"""

    def __init__(self, name, address, phone, gender, prefix):
        """ Initialize the object """
        self.userdata = {'name': name, 'address': address, 
                'phone': phone, 'gender': gender, 'prefix': prefix
               }

then

newperson = Person(name="Ben", address='9999 Gotham City, las vegas', phone='702-000-0000', gender ='male', prefix ='Waiter')
print newperson.userdata

returns

{'phone': '702-000-0000', 'gender': 'male', 'prefix': 'Waiter', 'name': 'Ben', 'address': '9999 Gotham City, las vegas'}

To your second question, if you pass a list instead of a string to the phone parameter that will show up as a list, will that work?

newperson = Person(name="Ben", address='9999 Gotham City, las vegas', phone=['702-000-0000', '111-827-3509'], gender ='male', prefix ='Waiter')
print newperson.userdata

returns

{'phone': ['702-000-0000', '111-827-3509'], 'gender': 'male', 'prefix': 'Waiter', 'name': 'Ben', 'address': '9999 Gotham City, las vegas'}
Sign up to request clarification or add additional context in comments.

1 Comment

Ah! makes sense. I think I was overthinking the problem. Thanks
1

If you have your data as list, you want to pass it as a parameter when creating instance of Person this why:

mydata = ["Ben", '9999 Gotham City, las vegas', '702-000-0000', 'male', 'Waiter']

class Person(object):
    """ Capture user demographics data"""
    def __init__(self, *data):
        self.userdata = {'name': data[0], 'address': data[1],
                'phone': data[2], 'gender': data[3], 'prefix': data[4]
               }
    def test(self):
            print self.userdata

>>>newPerson = Person(*mydata)
>>>newPerson.test()
{'phone': '702-000-0000', 'gender': 'male', 'prefix': 'Waiter', 'name': 'Ben', 'address': '9999 Gotham City, las vegas'}

But Here you have to keep your data organized in your list in standard way, Otherwise you better use dictionary instead of list, this way:

>>>mydata = {'name':"Ben", 'address':'9999 Gotham City, las vegas', 'phone':'702-000-0000', 'gender':'male', 'prefix':'Waiter'}

>>>class Person(object):
       """ Capture user demographics data"""

       def __init__(self, **kwargs):
            """ Initialize the object """
           self.userdata = kwargs
       def test(self):
            print self.userdata

>>>newPerson = Person(**mydata)
>>>newPerson.test()
{'phone': '702-000-0000', 'gender': 'male', 'prefix': 'Waiter', 'name': 'Ben', 'address': '9999 Gotham City, las vegas'}

4 Comments

Ah! lightbulb moment. I can actually iterate inside the __init__ to dynamically create my keys! def __init__(self, **kwargs): keys = sorted(kwargs.keys()) self.userdata = {key:kwargs[key] for key in keys}
Yes...You can do that...even better..:) .. but you cannot keep the order you want in the dictionary by using keys = sorted(kwargs.keys())
Yeah, I get your point. So I end up having name in the middle of my dictionary.
@Afloz .. There is not point in making such expression: self.userdata = {key:kwargs[key] for key in kwargs.keys()} .. it's the same as self.userdata = kwargs ...
0

You could achieve it by using keyword arguments in python (**kwargs). https://docs.python.org/2/tutorial/controlflow.html#keyword-arguments

3 Comments

That'd require me to do something like newperson = Person(name="Ben", address='9999 Gotham City, las vegas', phone='702-000-0000', gender='male', prefix='Waiter') which I don't want to do.
@Afloz if your data is already organized as a list like you've shown, i.e. data = ["Ben", '9999 Gotham City, las vegas', '702-000-0000', 'male', 'Waiter'] you can just wrap this with the tuple function and then call newperson = Person(*tuple(data)) if you don't want to call each variable by assignment, but I'm not sure what you mean when you say you don't want to use the construction newperson = Person(name="Ben", address='9999 Gotham City, las vegas', phone='702-000-0000', gender='male', prefix='Waiter')
Thanks for comment on **kwargs. I never knew how to use it until now! @Khalil's suggestion with your gave a nice idea.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.