当我们使用列表理解时,Python 会并行创建对象

标签 python oop

我在用 Python 编写一些简单的面向对象的东西时碰巧遇到了这个问题。假设我创建了一个具有增量 ID 的类(使用静态变量),并初始化了该类的新对象,期望每个新实例的 ID 自动增加 1。

这是我定义的类:

class Object:
   counter = 0

   def __init__(self):
      self.id = Object.counter
      Object.counter += 1

然后,我创建了一个固定长度的数组,其中包含 k 个 Object 类型的实例。我有两种方法可以做到这一点:

(1)

objects = [Object() for i in range(k)]

或 (2)

objects = [Objects()] * k

(1) 给出了我想要的结果,即每个实例都有一个增量 ID。有趣的是,(2) 生成的实例都具有相同的 ID = 0。所以我猜 (2) 与 (1) 做同样的事情,但是是并行的?

另外,我主要是用Java做OOP,这就是我实现增量ID的方式。我不知道这是否也适用于 Python。

如果我的问题是多余的,我很抱歉。我真的不知道如何称呼我正在做的这种事情(我猜是列表理解)。

非常感谢您的回复!

最佳答案

1 是正确的做法。它创建 k 个对象。

2 可能不是您想要的。它仅创建一个对象,然后创建一个“指向”同一对象 k 次的列表。

使用以下命令可视化 1 和 2 的结果

print(list(id(obj) for obj in objects))

许多人在第一次尝试实现二维数组时经常会遇到这种错误(如 2)。对于棋盘。

board = [[0] * 8] * 8  

它创建一行零,被引用 8 次。

要输入 8 个不同的行

board = [([0] * 8) for row in range(8)]

print([id(row) for row in board])

会显示差异

关于当我们使用列表理解时,Python 会并行创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58692535/

相关文章:

python - Django:根据字段的状态注释 Sum Case When

python - 根据过滤器使用 sqlalchamey 选择特定列值

python - 如何在 Python 中将日期更改为 YYYYMMDD?

Objective-C:什么时候知道你在滥用全局变量的 SIngleton 方法

python - 使用 __init__() 方法理解 Python super()

python - 我如何使用 GAE 和 Nosetest 模拟用户?

oop - 迭代具有不同属性的子类

用于 vector 类型类成员的 C++ getter

java - 使用多个相似的类高效地执行 CRUD 操作?

javascript - 为什么对象点表示法在 for...in 循环中不起作用?