为了账号安全,请及时绑定邮箱和手机立即绑定

Python 类实例的复制/引用问题

Python 类实例的复制/引用问题

慕少森 2023-09-05 20:36:36
我有以下类别的卡:class Card:    def __init__(self, number, position):        self.number = number        self.position = position * 50        self.rect = pg.Rect(self.position, 0, 50, 100)    def draw(self, surface):        pg.draw.rect(surface, green, (self.position, 0, 50, 100))        ## pg.draw.rect(surface, green, self.rect)我想并排创建 16 张不同的卡片,从 0 到 800,每张卡片的宽度= 50。他们的数字是 0 到 7,然后又是 0 到 7。对于这个问题我已经想出了一个解决方案,那就是:cards = []for n in range(16):    cards.append(Card(n%8, n))然而,一路上出现的破损解决方案给我留下了未解答的问题。例如:cards = [Card(n, 0) for n in range(8)] * 2for n in range(16):    cards[n].position = n * 50在这里,我意识到cards[0] is cards[8]回报True。结果是只有最后一半的卡片出现在屏幕上。显然,这与发生在以下情况的情况相同:cards = [Card(n, 0) for n in range(8)]cards.extend(cards)但我想将第二行更改为:cards.extend(cards[:])可以解决制作副本而不是参考的问题,但它仍然不起作用。这就是我想要解释的事情。有没有一种简单的方法可以解决前两种情况中的副本与参考问题?另一个问题是绘制方法的注释版本。在我使用的一些损坏的方法中,这个版本不起作用,因为它从不更新位置,位置总是卡在0。似乎在类之外,没有收到 的值,尽管我可以直接card.rect[0]在card.position内部self.position使用绘制方法。这里到底是怎么回事self.rect?
查看完整描述

2 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

循环

cards = []
for n in range(16):
   cards.append(Card(n%8, n))

运行16次。因此构造了 16 个Card对象并附加到一个列表中。最后,您将获得该类的 16 个独立实例Card和一个包含 16 个元素的列表。

但表达

cards  = [Card(n, 0) for n in range(8)] * 2

创建16 个Card对象。它构造 8 个Card对象和一个包含 16 个元素的列表,其中每个对象包含两次。Card (n, 0)仅被调用 8 次,因此只能有 8 个实例Card

这同样适用于

cards.extend(cards[:])

[:]创建列表的浅表副本。该列表仅包含对对象的引用。复制列表以及对对象的引用,但不复制对象本身,但不会Card创建新对象。


查看完整回答
反对 回复 2023-09-05
?
慕村9548890

TA贡献1884条经验 获得超4个赞

这与Python如何存储整数有关。从 -5 到 255 的“常见”整数已存储在内存中。当您分配像这样的变量时,您正在创建一个指向内存中已有的a = 1“硬编码”整数的指针,而不是实例化一个新整数。1任何时候您创建此范围内的整数时,它都不会是新数字,因此这将起作用:


>>> a = 7

>>> b = 7

>>> a is b

True

而对于此范围之外的数字:


>>> a = 1234

>>> b = 1234

>>> a is b

False

因此:


>>> a = [1, 2, 3]

>>> b = [1, 2, 3]

>>> a[0] is b[0]

True


>>> a is b

False


查看完整回答
反对 回复 2023-09-05
  • 2 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信