黑桃 A 的奇特案例(在 python3 中创建对象数组)
The curious case of the Ace of Spades (creating array of objects in python3)
我正在尝试创建一个对象(卡片)数组(卡片组)。为此,我在 Deck.construct() 方法内的 Deck.card 对象上使用 Card.construct() 方法。我能够成功地创建一个卡片对象数组 (Deck.cards),问题是所有这些都是黑桃 A,其中 52 个。这是创建数组的地方:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.card.showNice()
self.cards.append(self.card)
在分配之前正确打印了不同种类的纸牌,但由于某种原因,似乎只有黑桃 A 被附加到数组中。我真的不明白为什么会这样。
import random
class Card:
def __init__(self):
self.value = ''
self.values = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.suit = ''
self.suits = ['♥', '♦', '♣', '♠']
self.valit = (self.value, self.suit)
def construct(self, value, suit):
self.value = value
self.suit = suit
self.valit = (value, suit)
def random(self):
self.valit = (random.choice(self.values), random.choice(self.suits))
def show(self):
print(self.valit, end='')
def showNice(self):
print(self.value, self.suit, ' ', sep='', end='')
class Deck:
def __init__(self):
self.card = Card()
self.cards = []
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.cards.append(self.card)
def shuffleUp(self):
random.shuffle(self.cards)
def show(self):
for card in self.cards:
card.show()
print('\n')
def showNice(self):
for card in self.cards:
card.showNice()
print('\n')
...
#!/usr/bin/python
from environment.environment import *
class shuffleUpAndDeal():
deck = Deck()
deck.construct()
deck.shuffleUp()
deck.showNice()
if __name__ == '__main__':
shuffleUpAndDeal()
我对对象、类、方法等的整个概念都不熟悉,所以很可能我没有以正确的方式优化代码,非常感谢任何建议。提前致谢!
问题是,您一遍又一遍地重复使用 Card
的同一个实例,并在将其添加到列表后对其进行更改。您已将对同一张卡片的引用添加到列表中 52 次,并更改同一张卡片 52 次。这就是为什么它最终出现在最后一个组合上的原因。
注意这部分:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.cards.append(self.card)
print(self.cards) # I added this line
这是 print
打印的内容:
[<__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>]
看到 0x0377DB10
位了吗?那是对象的地址。请注意它们是如何完全相同的!每次调用 self.card.construct(value, suit)
时,您只是在更改该单个实例,包括已经在 self.cards
.
中的所有对它的引用
If you 运行 your test, then 改成 deck.card.suit
, then 运行 the再次测试,你会发现所有的卡片都同时发生了变化。
每次都创建一张新卡,这样您就不会经常覆盖同一个实例。
这是一个可以使用的修改版本。请注意我每次都是如何创建新卡片的:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
card = Card()
card.construct(value, suit)
self.cards.append(card)
print(self.cards)
这是新版本打印的内容:
[<__main__.Card object at 0x0376DB90>, <__main__.Card object at 0x0376DBB0>, <__main__.Card object at 0x0376DBD0>, <__main__.Card object at 0x0376DBF0>, <__main__.Card object at 0x0376DC10>, <__main__.Card object at 0x0376DC30>, <__main__.Card object at 0x0376DC50>, <__main__.Card object at 0x0376DC70>, <__main__.Card object at 0x0376DC90>, <__main__.Card object at 0x0376DCB0>, <__main__.Card object at 0x0376DCD0>, <__main__.Card object at 0x0376DCF0>, <__main__.Card object at 0x0376DD10>, <__main__.Card object at 0x0376DD30>, <__main__.Card object at 0x0376DD50>, <__main__.Card object at 0x0376DD70>, <__main__.Card object at 0x0376DD90>, <__main__.Card object at 0x0376DDB0>, <__main__.Card object at 0x0376DDD0>, <__main__.Card object at 0x0376DDF0>, <__main__.Card object at 0x0376DE10>, <__main__.Card object at 0x0376DE30>, <__main__.Card object at 0x0376DE50>, <__main__.Card object at 0x0376DE70>, <__main__.Card object at 0x0376DE90>, <__main__.Card object at 0x0376DEB0>, <__main__.Card object at 0x0376DED0>, <__main__.Card object at 0x0376DEF0>, <__main__.Card object at 0x0376DF10>, <__main__.Card object at 0x0376DF30>, <__main__.Card object at 0x0376DF50>, <__main__.Card object at 0x0376DF70>, <__main__.Card object at 0x0376DF90>, <__main__.Card object at 0x0376DFB0>, <__main__.Card object at 0x0376DFD0>, <__main__.Card object at 0x0376DFF0>, <__main__.Card object at 0x03775030>, <__main__.Card object at 0x03775050>, <__main__.Card object at 0x03775070>, <__main__.Card object at 0x03775090>, <__main__.Card object at 0x037750B0>, <__main__.Card object at 0x037750D0>, <__main__.Card object at 0x037750F0>, <__main__.Card object at 0x03775110>, <__main__.Card object at 0x03775130>, <__main__.Card object at 0x03775150>, <__main__.Card object at 0x03775170>, <__main__.Card object at 0x03775190>, <__main__.Card object at 0x037751B0>, <__main__.Card object at 0x037751D0>, <__main__.Card object at 0x037751F0>, <__main__.Card object at 0x03775210>]
请注意所有地址都不一样!他们现在都是不同的卡片了。
当我运行你的测试时,我得到:
2♥ K♥ 3♥ J♥ 6♥ 5♣ 7♣ 7♦ 8♣ 5♦ 3♣ Q♥ 10♣ 9♣ 9♥ A♦ 8♥ 9♠ 6♠ A♠ K♣ K♠ J♦ 2♦ 7♥ 10♠ 6♦ 6♣ 4♠ 5♠ K♦ 3♦ 4♥ 9♦ Q♠ 7♠ A♣ 4♣ 10♦ A♥ Q♦ 4♦ 5♥ J♣ 8♠ 3♠ J♠ Q♣ 8♦ 10♥ 2♣ 2♠
我想指出 construct
方法是不必要的。它正在做 Card
构造函数应该做的工作,但以一种不太直观的方式。构造函数的指向是construct
。想一想如果您忘记调用 construct
,卡片会变成什么样子。如果您只使用构造函数,就不可能忘记。
我正在尝试创建一个对象(卡片)数组(卡片组)。为此,我在 Deck.construct() 方法内的 Deck.card 对象上使用 Card.construct() 方法。我能够成功地创建一个卡片对象数组 (Deck.cards),问题是所有这些都是黑桃 A,其中 52 个。这是创建数组的地方:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.card.showNice()
self.cards.append(self.card)
在分配之前正确打印了不同种类的纸牌,但由于某种原因,似乎只有黑桃 A 被附加到数组中。我真的不明白为什么会这样。
import random
class Card:
def __init__(self):
self.value = ''
self.values = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.suit = ''
self.suits = ['♥', '♦', '♣', '♠']
self.valit = (self.value, self.suit)
def construct(self, value, suit):
self.value = value
self.suit = suit
self.valit = (value, suit)
def random(self):
self.valit = (random.choice(self.values), random.choice(self.suits))
def show(self):
print(self.valit, end='')
def showNice(self):
print(self.value, self.suit, ' ', sep='', end='')
class Deck:
def __init__(self):
self.card = Card()
self.cards = []
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.cards.append(self.card)
def shuffleUp(self):
random.shuffle(self.cards)
def show(self):
for card in self.cards:
card.show()
print('\n')
def showNice(self):
for card in self.cards:
card.showNice()
print('\n')
...
#!/usr/bin/python
from environment.environment import *
class shuffleUpAndDeal():
deck = Deck()
deck.construct()
deck.shuffleUp()
deck.showNice()
if __name__ == '__main__':
shuffleUpAndDeal()
我对对象、类、方法等的整个概念都不熟悉,所以很可能我没有以正确的方式优化代码,非常感谢任何建议。提前致谢!
问题是,您一遍又一遍地重复使用 Card
的同一个实例,并在将其添加到列表后对其进行更改。您已将对同一张卡片的引用添加到列表中 52 次,并更改同一张卡片 52 次。这就是为什么它最终出现在最后一个组合上的原因。
注意这部分:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
self.card.construct(value, suit)
self.cards.append(self.card)
print(self.cards) # I added this line
这是 print
打印的内容:
[<__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>, <__main__.Card object at 0x0377DB10>]
看到 0x0377DB10
位了吗?那是对象的地址。请注意它们是如何完全相同的!每次调用 self.card.construct(value, suit)
时,您只是在更改该单个实例,包括已经在 self.cards
.
If you 运行 your test, then 改成 deck.card.suit
, then 运行 the再次测试,你会发现所有的卡片都同时发生了变化。
每次都创建一张新卡,这样您就不会经常覆盖同一个实例。
这是一个可以使用的修改版本。请注意我每次都是如何创建新卡片的:
def construct(self):
for value in self.card.values:
for suit in self.card.suits:
card = Card()
card.construct(value, suit)
self.cards.append(card)
print(self.cards)
这是新版本打印的内容:
[<__main__.Card object at 0x0376DB90>, <__main__.Card object at 0x0376DBB0>, <__main__.Card object at 0x0376DBD0>, <__main__.Card object at 0x0376DBF0>, <__main__.Card object at 0x0376DC10>, <__main__.Card object at 0x0376DC30>, <__main__.Card object at 0x0376DC50>, <__main__.Card object at 0x0376DC70>, <__main__.Card object at 0x0376DC90>, <__main__.Card object at 0x0376DCB0>, <__main__.Card object at 0x0376DCD0>, <__main__.Card object at 0x0376DCF0>, <__main__.Card object at 0x0376DD10>, <__main__.Card object at 0x0376DD30>, <__main__.Card object at 0x0376DD50>, <__main__.Card object at 0x0376DD70>, <__main__.Card object at 0x0376DD90>, <__main__.Card object at 0x0376DDB0>, <__main__.Card object at 0x0376DDD0>, <__main__.Card object at 0x0376DDF0>, <__main__.Card object at 0x0376DE10>, <__main__.Card object at 0x0376DE30>, <__main__.Card object at 0x0376DE50>, <__main__.Card object at 0x0376DE70>, <__main__.Card object at 0x0376DE90>, <__main__.Card object at 0x0376DEB0>, <__main__.Card object at 0x0376DED0>, <__main__.Card object at 0x0376DEF0>, <__main__.Card object at 0x0376DF10>, <__main__.Card object at 0x0376DF30>, <__main__.Card object at 0x0376DF50>, <__main__.Card object at 0x0376DF70>, <__main__.Card object at 0x0376DF90>, <__main__.Card object at 0x0376DFB0>, <__main__.Card object at 0x0376DFD0>, <__main__.Card object at 0x0376DFF0>, <__main__.Card object at 0x03775030>, <__main__.Card object at 0x03775050>, <__main__.Card object at 0x03775070>, <__main__.Card object at 0x03775090>, <__main__.Card object at 0x037750B0>, <__main__.Card object at 0x037750D0>, <__main__.Card object at 0x037750F0>, <__main__.Card object at 0x03775110>, <__main__.Card object at 0x03775130>, <__main__.Card object at 0x03775150>, <__main__.Card object at 0x03775170>, <__main__.Card object at 0x03775190>, <__main__.Card object at 0x037751B0>, <__main__.Card object at 0x037751D0>, <__main__.Card object at 0x037751F0>, <__main__.Card object at 0x03775210>]
请注意所有地址都不一样!他们现在都是不同的卡片了。
当我运行你的测试时,我得到:
2♥ K♥ 3♥ J♥ 6♥ 5♣ 7♣ 7♦ 8♣ 5♦ 3♣ Q♥ 10♣ 9♣ 9♥ A♦ 8♥ 9♠ 6♠ A♠ K♣ K♠ J♦ 2♦ 7♥ 10♠ 6♦ 6♣ 4♠ 5♠ K♦ 3♦ 4♥ 9♦ Q♠ 7♠ A♣ 4♣ 10♦ A♥ Q♦ 4♦ 5♥ J♣ 8♠ 3♠ J♠ Q♣ 8♦ 10♥ 2♣ 2♠
我想指出 construct
方法是不必要的。它正在做 Card
构造函数应该做的工作,但以一种不太直观的方式。构造函数的指向是construct
。想一想如果您忘记调用 construct
,卡片会变成什么样子。如果您只使用构造函数,就不可能忘记。