简体   繁体   中英

Python : Assign value of a function result / variable to a class

I have made a simple, test program to experiment using classes. It creates a "person" class, which takes the arguments of name and age. I am now trying to create an interactive program that allows the user to manage a list of people, like a register or address book. They can create a new person, as shown in the function below.

def createnew():
    newname = input("What is their name?")
    newage = input("How old are they?")

    newperson = Person(newname, newage)

Of course the problem with the above is it assigns newname literally rather than the string value of "newname". So I tried

newperson.lower() = Person(newname, newage)
str(newperson) = Person(newname, newage)
newperson[0:] = Person(newname, newage)

but they all return the error, can't assign to function call. My question is how do I access the value of the variable newname and assign it to the Person, or any other class.

Note: I am a n00b/newb, meaning I have not come from another language, and am following a book. Please explain any answers given if they are not ridiculously obvious.

Many Thanks.

To make it slightly clearer, I am trying to make the user-inputted value for the new person's name the object name ( in my example it is newperson )

Update:

Thanks for all the answers, I gather it's not a great idea to allow the user to set variable names so I re-jigged my code. I made a dictionary which after the user has created a new person, writes the data given by the class str function to the key of the given name. While this means I can't then access the object later on, because newperson will have been overwritten, it allows me to build a list of people with a set of data which is what I wanted to do in the first place, I just mistakingly thought it would be easier to set the object name. Thanks again.

If I understand you correctly, what you want is to create the Person object, then create a global variable with the name being the name of the person.

This is bad.

What you really want is a way to store people objects and retrieve them later by their names. So, use a dictionary:

people = {}

def createnew():
    ...
    people[newname] = Person(newname, newage)

Then later, you can access the Person in the dictionary:

print(people['name of the person'])

(I'm assuming that you're using Python 3, since you're using input() rather than raw_input() as in Python 2.x)

If you really must create a new variable (which is bad, since people's names aren't usually valid Python identifiers), use the globals() function:

>>> globals()['foo'] = 2
>>> foo
2

but I include this for the sake of completeness. Don't use this!

Are you using Python 2 or Python 3? I'm guessing that maybe your book is written for Python 3 and you are using Python 2. I think your first program should work in Python 3, but in Python 2 the input function probably doesn't do what you expect it to. The raw_input function would be better. Let me know which version of Python you're using and I'll try to give you more specific help. You should see the version number any time you start the Python interpreter or when you run python -V at a command-line.

This version of your code should work in Python 2:

def createnew():
    newname = raw_input("What is their name?")
    newage = int(raw_input("How old are they?"))

    person = Person(newname, newage)

I changed input to raw_input . As voithos suggests below, I used the "int" function to convert the input (with is a string) into an integer number. I also changed the last line to store the Person instance in a new variable person instead of newname , because it can be quite confusing to re-use the same variable for two different types of value.


The reason input gives you surprising results becomes clear if you check the documentation for that function:

http://docs.python.org/library/functions.html#input

It reads input and then tries to evaluate it as a Python expression! When you type in a name you get an error because it's not a variable name. Because this is quite surprising and not often what you actually want, in Python 3 they changed it, but it does mean that books and tutorials for Python 2 and 3 need to be different, and can itself result in some confusion.

I'm not entirely sure what the problem is, but the code you show has some inconsistencies.

  • newname is a reference to a string object, you then bind this reference to a Person object in the last line. This is bad design because it confuses the reader. Better call your Person object something different, for example newPerson = Person( ... ) .
  • newname.lower() calls the lower() function on the newname object - that would work if newname still was a string , but now it is a Person . Have you defined a def lower(self) member function in the Person class? How does the class look like?
  • str(newname) is a noop if newname is still a string . If it is a Person object you have to define a def __str__(self) member function that returns a string representation of your Person .

All in all I'm unsure what you really want, but a Person class might look like this:

class Person(object):
    def __init__(self):
        self.name=raw_input("What is their name? ").capitalize()
        self.age=int(raw_input("How old are they? "))

    def __str__(self):
        return "My name is %s and I'm %d years of age." % (
            self.name, self.age)

Usage:

p=Person()
print p

Sidenote: It's maybe a bad design to use raw_input inside of __init__ , and the __str__ function might better return Person(name=%s, age=%d) % ... , but then this is just an example how it works.

All of those function calls return values instead of variables, so they can't be altered. In math terms, its like trying to say 2 = 7 + 4 . Since 2 isn't a variable and can't really be assigned/changed that way, it doesn't make much sense to do that and the poor interpreter is giving you its tragic plea for help. Variables on the other hand, as you probably already know, can be assigned that way in the form of x = 7 + 4 . Changing the value contained in the variable x is perfectly fine because variables contain values, but trying to change the value of another value is impossible.

What you need to do is find the variable you want to change, put it to the left of the equals sign, and put the value you want to assign to it on the right side. When you say Person(newname, newage) , you are creating a value, in this case an object, that needs to be assigned to a variable so it can be kept and used later on instead of just discarded instantly:

def createnew():
    newname = input("What is their name?") #remember to indent these if you want them 
    newage = input("How old are they?")    #to be part of the function!
    newPerson = Person(newname, newage) 
    return newPerson

Now that newPerson contains the value of the person you just created, you can access the variables inside it and assign their values just like any other. In order to do this, you need to know the names of the variables used, which are defined in the constructor you wrote that probably looks something like this:

class Person:
    def __init__(self, name, age):
        self.name = name      #the variable that contains the person's name is called 'name'
        self.age = age       #the variable that contains the person's age is called 'age'

def createnew():
    newname = input("What is their name?") #remember to indent these if you want them 
    newage = input("How old are they?")    #to be part of the function!
    newPerson = Person(newname, newage) 
    return newPerson

newperson = createnew() #will prompt you to enter name and age for this person and assign them

print( "person's old name: " + newperson.name )    
newperson.name = input("What's is their new name?") #second thought, you want to change Bob's name
print( "person's new name: " + newperson.name )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM