为什么可以用这种方式初始化对象?


class Pizza:
def __init__(self, ingredients):
self.ingredients = ingredients
def __repr__(self):
return f'Pizza({self.ingredients!r})'

为什么这个Pizza(['mozzarella', 'tomatoes'])可以工作?通常我会这样做Pizza1 = Pizza(['mozzarella', 'tomatoes'])

在这种情况下:

class Pizza():
pass

如果我输入两个Pizza()怎么办? 这两个Pizza()是新对象吗? 我已经在我的 Vscode 中尝试过这个,但它返回相同的 ID 地址。

Pizza(['mozzarella', 'tomatoes'])是一个表达式,就像1+1f(1, 2, 3)"dogs"一样。在运行时,此表达式的计算结果为Pizza的新实例,与程序中的任何其他实例不同。因此,您可以编写如下内容:

def printPizza(pizza):
print("Here's a pizza")
print(repr(pizza))
printPizza(Pizza(['mozzarella', 'tomatoes']))

当你有一个像pizza = Pizza(['mozzarella', 'tomatoes'])这样的语句(不是表达式!(时,运行时发生的事情是计算Pizza(...)表达式的结果(即Pizza的新实例(被分配给pizza变量。当然,那么你可以很容易地运行printPizza(pizza).

如果Pizza()表达式运行两次,则每次都会返回一个不同于程序中当前处于活动状态的任何其他实例的Pizza实例。但是,如果从较早的Pizza()调用返回的实例不再处于活动状态,则对Pizza()的新调用可能与较早的实例具有相同的 id(不再可用(。

例如,在 IDLE 中:

>>> id(Pizza())
65959272
>>> id(Pizza())
65959272

由于在执行对Pizza()的第二次调用时,从第一次调用Pizza()返回的实例不再存储在任何位置,因此可以安全地重用 id。(永远不会有两个具有相同ID的比萨饼同时活着。

但是如果你做这样的事情:

def printIds(pizza1, pizza2):
print(id(pizza1))
print(id(pizza2))
printIds(Pizza(), Pizza())

您将看到打印了两个唯一 ID。这是因为两个披萨实例在打印 id 时都处于活动状态(一个存储在pizza1中,另一个存储在pizza2中(,因此每个实例都必须具有唯一的 ID。

最新更新