【问题标题】:Python : Assign value of a function result / variable to a classPython:将函数结果/变量的值分配给类
【发布时间】:2012-03-17 17:54:59
【问题描述】:

我制作了一个简单的测试程序来使用类进行实验。它创建了一个“人”类,它接受名称和年龄的参数。我现在正在尝试创建一个交互式程序,该程序允许用户管理人员列表,例如寄存器或地址簿。他们可以创建一个新人,如下面的函数所示。

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 函数给出的数据写入给定名称的键。虽然这意味着我以后无法访问该对象,因为 newperson 将被覆盖,但它允许我使用一组数据构建一个人员列表,这是我首先想要做的,我只是错误地认为设置对象名称会更容易。 再次感谢。

【问题讨论】:

  • 您使用的是 Python 2 还是 Python 3?

标签: python function variables


【解决方案1】:

如果我理解正确,您想要的是创建 Person 对象,然后创建一个名称为人名的全局变量。

这很糟糕。

您真正想要的是一种存储人员对象并在以后通过其名称检索它们的方法。所以,使用字典:

people = {}

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

然后,您可以访问字典中的 Person:

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

(我假设您使用的是 Python 3,因为您使用的是 input() 而不是 Python 2.x 中的 raw_input()

如果您真的必须创建一个新变量(这很糟糕,因为人们的名字通常不是有效的 Python 标识符),请使用 globals() 函数:

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

但为了完整起见,我将其包括在内。不要用这个!

【讨论】:

  • @user1276048,你不想那样做。不,认真的。不要那样做。永远不要那样做。在任何情况下,您都不应尝试使用用户输入作为变量的名称。这个答案是您尝试做的正确方法。
  • @user1276048:是的,这就是写这个答案的人认为你的意思。这不是一个好主意。它使你的生活复杂化。作为程序员,您需要区分您如何看待数据和用户如何看待数据。创建新的Person 后,您需要知道它的名称以便编写更多使用它的代码。如果用户控制了变量名,那么你就有点卡住了。用户的信息已经存储在对象中。您不需要它反映在变量名称中。 这不是变量的用途
【解决方案2】:

您使用的是 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)

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


如果您查看该函数的文档,input 给您带来令人惊讶的结果的原因就很清楚了:

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

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

【讨论】:

  • 更准确地说,在 Python 2 中 raw_input() 抓取输入的 string 表示,而不修改它(因此是“原始”)。另一方面,input() 基本上等同于eval(raw_input()),这意味着它尝试将字符串作为 Python 表达式求值。因此,如果输入是像“31”这样的数字,那么input() 将返回一个整数。如果它是“5.4”之类的东西,它会返回一个浮点数等。通常手动转换类型更易读,更不容易出错,比如int(raw_input())
  • 我认为我没有说得很清楚,我试图使用分配给 newname 的值作为类的名称。因此,如果我将 Bob 作为输入的名称,它将创建 Bob 作为 Person 类的对象。
【解决方案3】:

我不完全确定问题出在哪里,但您显示的代码有一些不一致之处。

  • newname 是对 string 对象的引用,然后在最后一行将此引用绑定到 Person 对象。这是一个糟糕的设计,因为它让读者感到困惑。最好将您的 Person 对象命名为不同的名称,例如 newPerson = Person( ... )
  • newname.lower() 调用 newname 对象上的 lower() 函数 - 如果 newname 仍然是 string,但现在它是 Person,这将起作用。您是否在Person 类中定义了def lower(self) 成员函数?这门课怎么样?
  • 如果newname 仍然是string,则str(newname) 是一个noop。如果它是 Person 对象,您必须定义一个 def __str__(self) 成员函数,该函数返回您的 Person 的字符串表示形式。

总而言之,我不确定您真正想要什么,但 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

旁注:__init__ 内部使用raw_input 可能是一个糟糕的设计,而__str__ 函数可能会更好地返回Person(name=%s, age=%d) % ...,但这只是一个示例有效。

【讨论】:

  • 我认为我没有说得很清楚,我试图使用分配给 newname 的值作为类的名称。因此,如果我将 Bob 作为输入的名称,那么它将创建 Bob 作为 Person 类的对象。感谢您的示例课程,但我已经有类似的课程了。
【解决方案4】:

所有这些函数调用都返回值而不是变量,因此它们无法更改。用数学术语来说,就像试图说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 )

【讨论】:

  • 我认为您比大多数人更了解我想要的东西,但是有没有办法让用户可以分配类对象名称 thingy,在您的示例中是 newperson。这就是我一直在努力做的。
  • 当您说 newperson = Person(newname, newage) 时,我如何允许用户设置“newperson”是什么
  • @user1276048 如果您引用变量的名称,则最终用户无法控制它。当您的程序被解释/运行时,构成变量名称的所有文本都将被擦除并转换为内存中的地址。变量的名称只是一个简写形式,因此程序员可以参考它转换到的地址和存储在其中的值。您无法更改变量的名称,但您可以存储它们的值并按照其他人的建议根据需要检索它们,这可能是您真正想要做的。 :D
猜你喜欢
  • 2010-10-02
  • 2019-01-07
  • 2020-10-05
  • 2013-11-12
  • 1970-01-01
  • 2022-07-02
  • 2011-04-03
  • 2011-10-22
  • 2021-08-21
相关资源
最近更新 更多