2012-03-17 96 views
3

我已经做了一个简单的测试程序来使用类进行实验。它创建了一个“人”类,它接受了名称和年龄的论点。我现在正在尝试创建一个交互式程序,允许用户管理一个人员列表,如注册表或通讯簿。他们可以创建一个新的人,如下面的功能所示。Python:将函数结果/变量的值赋给一个类

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

    newperson = Person(newname, newage) 

当然,上面的问题是,它的字面意思是分配newname,而不是字符串值“newname”。所以我试了

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

但是他们都返回错误,不能分配给函数调用。 我的问题是如何访问变量newname的值并将其分配给Person或任何其他类。

注:我是一个n00b/newb,这意味着我不是来自另一种语言,并且正在阅读一本书。如果他们不是很明显,请解释给出的答案。

很多谢谢。

它弄得有一点更清晰,我试图让新的人的名字对象名称,用户输入的值(在我的例子是newperson)

更新:

感谢所有答案,我认为允许用户设置变量名称并不是一个好主意,所以我重新调整了我的代码。我创建了一个字典,在用户创建新人之后,将类str函数给出的数据写入给定名称的键。虽然这意味着我以后不能访问该对象,因为新人将被覆盖,它允许我用一组数据创建一个列表,这是我想要做的第一个地方,我只是错误地认为设置对象名称会更容易。 再次感谢。

+0

你使用Python 2或Python 3? – imm 2012-03-17 17:58:18

回答

5

如果我正确地理解了你,你想要的是创建Person对象,然后创建一个全局变量,其名称就是这个人的名字。

这很糟糕。

你真正想要的是一种方法来存储人物对象,并在以后用他们的名字检索它们。因此,使用字典:

people = {} 

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

后来的后来,你可以访问该人在词典:

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

(我假设你使用Python 3,由于您使用如Python 2中的input()而不是raw_input()。X)

如果你真的必须创建一个新的变量(这是不好的,因为人的名字通常不是有效的Python标识符),使用globals()功能:

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

但我包括这对为了完整性。不要使用这个!

+3

@ user1276048,你不想这样做。不,认真。不要这样做。永远不要这样做。在任何情况下,您都不应该试图将用户输入用作变量的名称。这个答案是你尝试去做的正确方法。 – 2012-03-17 18:53:42

+2

@ user1276048:是的,这就是写这个答案的人认为你的意思。这不是一个好主意。它使你的生活变得复杂。您需要区分作为程序员的您如何考虑用户对数据的看法。创建了新的Person后,您需要知道它是什么,才能编写更多使用它的代码。如果用户在控制变量名称,你有点卡住了。用户的信息已存储在对象中。您不需要将其反映在变量名称中。 **这不是**的变数。 – 2012-03-17 20:41:09

1

你使用Python 2还是Python 3?我在猜测,也许你的书是为Python 3编写的,而且你正在使用Python 2.我认为你的第一个程序应该在Python 3中工作,但在Python 2中,input函数可能不会达到你期望的效果。 raw_input功能会更好。让我知道你正在使用哪个版本的Python,我会尽力给你更具体的帮助。每次启动Python解释器或在命令行运行python -V时,都应该看到版本号。

这是你的代码的版本应该在Python 2工作:

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

    person = Person(newname, newage) 

我改变inputraw_input。正如下面的voithos建议的那样,我使用“int”函数将输入(使用字符串)转换为整数。我还更改了最后一行以将Person实例存储在一个新变量person而不是newname中,因为对于两种不同类型的值重复使用相同变量可能会相当混淆。


原因input为您提供了令人惊讶的结果,如果你检查的文档,该功能变得清晰:

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

它读取输入,然后尝试将其评估为Python表达式!当你输入一个名字时,你会得到一个错误,因为它不是一个变量名。因为这非常令人惊讶,并且通常不是你真正想要的,所以在Python 3中它改变了它,但这确实意味着Python 2和Python 3的书籍和教程需要不同,并且本身可能会导致一些混淆。

+0

更确切地说,在Python 2中'raw_input()'抓取输入的_string_表示,而不修改它(因此是“原始”)。另一方面,'input()'基本上等同于'eval(raw_input())',这意味着它试图将字符串评估为Python表达式。所以,如果输入是像'31'这样的数字,那么'input()'会返回一个int。如果它是'5.4'的东西,它会返回一个浮点数等。它通常更具可读性并且不易出错,只是手动转换类型,la'int(raw_input())' – voithos 2012-03-17 18:07:29

+0

我不认为我做了我自己很清楚,我试图用分配给newname的值作为这个类的名字。因此,如果我将Bob作为输入的名称,它将创建Bob作为Person类的对象。 – user1276048 2012-03-17 18:38:13

0

我不完全确定问题是什么,但是您显示的代码有一些不一致之处。

  • newname是一个string对象的引用,那么你在最后一行绑定这个参照Person对象。这是糟糕的设计,因为它会让读者感到困惑。最好打电话给你的Person物品,例如newPerson = Person(...)
  • newname.lower()调用newname对象的lower()功能 - 如果newname仍然是一个string,将工作,但现在它是一个Person。您是否在Person类中定义了def lower(self)成员函数?这个班怎么样?
  • str(newname)是一个noop如果newname仍然是string。如果它是一个Person对象,则必须定义一个def __str__(self)成员函数,该函数返回Person的字符串表示形式。

所有的一切我不能确定你真正想要的,但一个人的类可能是这样的:

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) 

用法:

p=Person() 
print p 

旁注:这可能是糟糕的设计使用raw_input里面的__init__,和__str__功能可能会更好地返回Person(name=%s, age=%d) % ...,但这只是一个例子,它是如何作品。

+0

我认为我没有把自己说得很清楚,我试图用分配给newname的值作为班级的名字。因此,如果我将Bob作为输入的名称,它将创建Bob作为Person类的对象。感谢你的例子,但我已经有了类似的例子。 – user1276048 2012-03-17 18:39:38

0

所有这些函数调用都会返回值而不是变量,所以它们不能被修改。用数学术语来说,就像试图说2 = 7 + 4。由于2不是一个变量,并且不能真正地以这种方式进行分配/改变,所以这样做并不合理,而且这位可怜的口译员正在给你一个悲哀的求助呼吁。另一方面,您可能已经知道,变量可以以x = 7 + 4的形式分配。更改变量x中包含的值是完全正确的,因为变量包含值,但试图更改的值,但是另一个值是不可能的。

你需要做的是找到你想改变的变量,把它放在等号的左边,并把你想要赋值的值放在右边。当你说Person(newname, newage),你正在创建一个值,在这种情况下一个对象,需要被分配给一个变量,因此可以保持,后来,而不只是丢弃立即使用:

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包含您刚刚创建的人的价值,您可以访问其中的变量并为其赋值,就像其他变量一样。为了做到这一点,你需要知道所使用的变量的名称,这是在你写的构造函数定义,可能看起来是这样的:

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) 
+0

我认为你比大多数人更了解我想要的东西,但是有没有办法让用户可以分配类对象名thingy,在你的例子中它是新人。那就是我一直在努力去做的事情。 – user1276048 2012-03-17 18:40:58

+0

当你说newperson = Person(newname,newage) – user1276048 2012-03-17 18:49:56

+0

@ user1276048时,我该如何让用户设置什么“新人”?如果你正在接触变量的名字,最终用户无法控制它。当程序被解释/运行时,组成变量名称的所有文本都将被擦除并转换为内存中的地址。变量的名称只是一个简写,所以程序员可以参考它转换的地址和存储在其中的值。你不能改变变量的名字,但你可以存储它们的值并根据需要检索它们,这可能是你真正想要做的。 :d – 2012-03-19 00:57:14