10

I'm just learning to program and am learning Python as my first language. As an exercise I'm trying to write an address book program. New contact are created by the user using the command prompt. New contacts are object instances of the Contacts class.

I know how to instantiate a class object from within the code, but how do I create one with a variable name based on user input? Say I prompt the user for a name -- how do I take that info and use it for the variable name of my new object?

Thanks!!

jdi
  • 90,542
  • 19
  • 167
  • 203
ShaunSoda
  • 101
  • 1
  • 1
  • 4

2 Answers2

21

From the comments, it turns out you are asking about something that gets asked more than once on here. "How can I create dynamically named variables".

Answer: Don't do this. Chances are there are better ways to solve the problem.

Explanation:

If you were to create dynamically named variables, you don't quite have a good handle to them once they are created. Sure there are ways to check the globals and local scopes to see what is there. But the fact is that you should have definitive control over what is being created.

What you should do is put them into a dictionary:

people = {}
name = raw_input("What name? ") # "person"
people[name] = User(name)

print people
# {'person': <User: "person">}

print people.keys()
# ['person']

This way you are not creating arbitrary variables in your namespace. You now have a dictionary of keys and objects as values. It is also a can of worms to allow a user-supplied input to drive the naming of a variable.

For more info, just search on here for the same topic and see numerous examples of why you should not do this. No matter what examples you see showing you how to use globals(), etc, please take my advise and don't go that route. Love and enjoy..and maybe hug and kiss, your dictionary.

References:

Community
  • 1
  • 1
jdi
  • 90,542
  • 19
  • 167
  • 203
  • Thanks for the help! Maybe I wasn't precise enough with my question though. I know how to assign values to the fields of an object based on user input, but what about the actual name of the object? – ShaunSoda Jul 06 '12 at 00:15
  • Yes, you need to be much much more detailed when you ask for help here. Are you talking about the representation of the instance when you print the object? What do you mean by the "name" of the object? – jdi Jul 06 '12 at 00:19
  • Hehe. Sorry, as I said I'm just learning to program so bear with me on the terms. When you create a new class object you give it a name. My class is called Contacts, so if I were to create new objects they might be called contact1, contact2, etc. Maybe these are called identifiers? I want to name the identifier of each object whatever the user inputs. – ShaunSoda Jul 06 '12 at 00:20
  • It sounds to me like you are asking to create the actual variable name from the user input, such that if they input `"person"`, it would create a variable object like: `person = User()`. Is that what you mean? – jdi Jul 06 '12 at 00:24
  • YES!!! That is exactly what I mean. Is that possible? – ShaunSoda Jul 06 '12 at 00:30
  • 2
    Ok so now that we have that sorted out... don't do it. Its a seems to be a common question with people learning to program. Every time the question is asked "How can I create dynamic variable names" the answer is always "There is a better solution to your problem". I will update my answer – jdi Jul 06 '12 at 00:31
  • Ok, I thought I understood this but maybe not. I do see why you should create a dictionary with the name of each contact as the 'key'. What I want do for the 'value' of each key, though, is assign an instance of a class where personal info such as email and phone# is stored. The issue is that I cant figure out how to generate a new class object and tie it to the key. More specifically, when you create a new class object you need to give it a name. How would you give each of these a unique name that could then be tied to dictionary keys? Thanks for your time!!! – ShaunSoda Jul 06 '12 at 13:05
  • You keep refering to "giving the new instance" a name which doesnt make any sense to me. The class can have instance attributes like name, phone, email. This is what the first version of my answer was showing you. It set just a name attribute on the instance. But you said that you already new that part. It just sounds like you want that again but with more attributes. You can simply assign the new Contact() instance as each value in the dict. Honestly, PLEASE update your question up top with an example of what you want to achieve. – jdi Jul 06 '12 at 16:10
  • This game of guessing your thoughts is not working out. I want to help, but you are using terminology that may not be correct. – jdi Jul 06 '12 at 16:11
  • Nevertheless, in Perl you can create dynamically named variables in the most simple way: if $name contains the name, ${$name} will be a variable of that name... Why should this be good for Perl and wrong for Python? – yannis Sep 19 '15 at 08:06
  • @yannis I don't think this is specific to python really. I have seen the same question asked for other languages and it is usually a similar answer. My take is that it is about best practices. It's easy to do this in python too, by assigning to globals dict. Regardless of whether this is easy in Perl, I maintain that it is still bad design in either language to do it. – jdi Sep 19 '15 at 08:12
0

You do not make clear why you would want to instantiate objects of which the name is determined as runtime as you wish. It is important to realize that that is not common practice.

It is possible, though, using the setattr builtin:

setattr(someobject, name, user)

Somewhat more normal usage would be to use a dictionary. So if you have more than one user instance and want to store them, you could store them in a dictionary like below. This would allow you to reference the object by name.

class User(object):

    def __init__(self, name):
        self.name = name


users = {}

name = raw_input("What name?")
users[name] = User(name)


print users
print users['Andre'].name

Sample output:

What name?Andre
{'Andre': <__main__.User object at 0x7f6b418a8710>}
Andre
Andre Blum
  • 391
  • 3
  • 6
  • Unfortunately, this ended up not being what the OP wanted. I provided this same answer and then had to change it. – jdi Jul 06 '12 at 00:43
  • barf. also important is what others will learn from stumbling on this question. – Andre Blum Jul 06 '12 at 00:55