Python对象实例化及使用列表

4

我是一个编程新手,正在尝试自学编程。我目前正试图学习如何从类中构建对象,并且我认为我已经理解了这个过程。我的当前任务是将对象添加到列表中并打印该列表。最终,我正在尝试构建一个程序,创建一个对象并在编号列表中列出已创建的每个对象,例如:

1 - tomato, red
2 - corn, yellow
etc...

首先,我只是尝试构建它的基本部分。这是我制作的内容:

# Builds objects on instantiation for a vegetable and color
class Veg:
    def __init__(self, name, color):
        self.name = name
        self.color = color
        print('You have created a new', self.color, self.name, end='.\n')

# Function to create a new vegetable and store it in a list
def createVeg():
    name = input('What is the name of the Vegetable? ')
    color = input('What color is the vegetable? ')
    Veg(name, color)
    vegList.append(Veg)
    return

# Initialize variables
vegList = []
choice = 'y'

# Main loop
while choice == 'y':
    print('Your basket contains:\n', vegList)
    choice = input('Would you like to add a new vegetable? (y / n) ')
    if choice == 'y':
        createVeg()
    if choice == 'n':
        break

print('Goodbye!')

当我运行这个程序时,会得到以下结果:
Your basket contains:
 []
Would you like to add a new vegetable? (y / n) y
What is the name of the Vegetable? tomato
What color is the vegetable? red
You have created a new red tomato.
Your basket contains:
 [<class '__main__.Veg'>]
Would you like to add a new vegetable? (y / n) y
What is the name of the Vegetable? corn
What color is the vegetable? yellow
You have created a new yellow corn.
Your basket contains:
 [<class '__main__.Veg'>, <class '__main__.Veg'>]
Would you like to add a new vegetable? (y / n) n
Goodbye!

据我所知,除了打印列表之外,一切都正常,但我无法解决这个问题。它似乎在添加列表属性,但未显示对象。我还尝试了“for”循环,但结果相同。


蔬菜购物者RPG - 爱它! - Marcin
3个回答

6

一切都按设计要求运作。字符串<class '__main__.Veg'>Veg类实例的表示形式

您可以通过为您的类提供__repr__方法来自定义该表示形式:

class Veg:
    # ....

    def __repr__(self):
        return 'Veg({!r}, {!r})'.format(self.name, self.color)

所有__repr__函数需要做的就是返回一个合适的字符串。

使用上述示例中的__repr__函数,您的列表将如下所示:

[Veg('tomato', 'red'), Veg('corn', 'yellow')]

您需要确保实际上将新实例添加到现有实例中。不要这样写:

Veg(name, color)
vegList.append(Veg)

做这个:

newveg = Veg(name, color)
vegList.append(newveg)

我需要研究一下这个方法才能理解它。我在书中还没有看到过这个。然而,当我插入它时,得到的结果与之前相同。 - Gregory6106
确保它是你的 Veg 类的一部分。如果你仍然在结果中看到 <class '__main__.Veg'>,那么你没有将它添加到正确的位置和/或没有重新加载你的代码。 - Martijn Pieters
1
他不应该使用__repr__来表示类的可读版本;__str__是为此保留的。__repr__是为类的机器可读版本保留的。请参阅http://docs.python.org/3/reference/datamodel.html?highlight=__repr__#object.__repr__。 - jeffknupp
@jknupp:但是在打印列表时,repr() 会自动使用。请注意,我的示例创建了一个合理的机器表示形式,可以用来重新创建 Veg 对象。 - Martijn Pieters
1
@MartijnPieters 没错,这就是为什么他不应该打印列表,因为他真正想要的是打印它的内容。 - jeffknupp

2
问题出在这几行代码上。
Veg(name, color)
vegList.append(Veg)

你正在创建一个新的蔬菜对象,但没有为其指定任何内容。然后将蔬菜的类型添加到列表中。此外,你需要通过向类中添加__str__方法来告诉Python如何以人类可读的方式打印Veg对象。最后,如果直接打印列表(print vegList),将获得列表内容的机器可读表示,这并不是你想要的。遍历列表元素并直接打印它们将起作用。
这是带有所需更改的工作版本:
# Builds objects on instantiation for a vegetable and color
class Veg:
    def __init__(self, name, color):
        self.name = name
        self.color = color
        print('You have created a new', self.color, self.name, end='.\n')

    def __str__(self):
        return 'One {} {}'.format(self.color, self.name)

# Function to create a new vegetable and store it in a list
def createVeg():
    name = input('What is the name of the Vegetable? ')
    color = input('What color is the vegetable? ')

    vegList.append(Veg(name, color))
    return

# Initialize variables
vegList = []
choice = 'y'

# Main loop
while choice == 'y':
    print('Your basket contains:\n')
    for veg in vegList:
        print(veg)
    choice = input('Would you like to add a new vegetable? (y / n) ')
    if choice == 'y':
        createVeg()
    if choice == 'n':
        break

print('Goodbye!')

1

Your issue is here:

def createVeg():
    name = input('What is the name of the Vegetable? ')
    color = input('What color is the vegetable? ')
    Veg(name, color) # 1
    vegList.append(Veg) # 2
    return

我已经在#1处注释的行创建了一个新的veg对象实例。然而,它并没有做任何事情。它没有将其存储在任何地方或命名,就像你写了a = Veg(name, color)一样。基本上,它创建了对象,然后忘记了它。

我已经在#2处注释的行将Veg类附加到列表中,而不是类的实例。这就像将整数的概念添加到列表中,而不是添加实际的整数5。

尝试用以下内容替换这两行...

v = Veg(name, color)
vegList.append(v)

一旦你这样做了,你仍然希望按照Martijn Pieters的答案进行操作,以正确打印对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接