Class 属性定义为另一个列表类型的长度 class 属性不会自行更新并且总是 returns 相同的值
Class attribute defined as a length of another List Type class attribute doesn't update itself and always returns the same value
我正在为纸牌游戏编写代码 'War'。在定义“Deck”class 时,我定义了一个属性“self.cards”,它给出了一副纸牌中当前所有纸牌的列表。我还定义了一个属性“self.length”,它应该给出“self.cards”属性的长度。
但是,当我使用 表达式 deck.length
时,它 returns 一个固定值 ,即使牌组中的牌也不会改变("self.cards") 是 removed/added。另一方面,当我使用 表达式 len(deck.cards)
时,它 returns 所需的输出 (即甲板的更新大小)。
代码为:
# I've used only two suits and three ranks to explain this problem
suits = ('Hearts','Spades')
ranks = ('Queen','King','Ace')
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
class Deck():
def __init__(self):
# Create an empty deck and fill it with the available cards
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append(Card(suit,rank))
self.length = len(self.cards)
def deal_top_card (self):
self.cards.pop(0)
deck = Deck()
# Removing Three cards one after the other
deck.deal_top_card()
deck.deal_top_card()
deck.deal_top_card()
print(f"Length according to length attribute = {deck.length}")
print(f"Length of the list of cards = {len(deck.cards)}")
上面代码的输出是:
Length according to length attribute = 6
Length of the list of cards = 3
您只是更新了 init() 方法中的 self.length。因此它不会在您每次弹出卡片时自行更新。 Init 仅在您创建对象时调用一次。您应该添加:
def deal_top_card (self):
self.cards.pop(0)
self.length = len(self.cards)
每次出卡更新长度
At 属性不会自行更新。看起来你想要一个 属性 或一个方法。
A 属性 是您想要访问 length
时要使用的东西,就好像它是一个属性一样。它还可以让您控制如果某些代码想要覆盖长度的值会发生什么:
class Deck:
....
@property
def length(self):
return len(self.cards)
...
print(f"Length according to length property = {deck.length}")
一个方法类似,但你显式调用它:
class Deck:
....
def length(self):
return len(self.cards)
...
print(f"Length according to length method = {deck.length()}")
最后,你可以定义魔术__len__
并调用len(deck)
,因为长度的概念适用于Python中的许多类型。
此外,您可能会认为 Deck
是一个与“卡片序列”非常相似的概念,因此将其作为 list
的子类可能有意义,在这种情况下您根本不需要定义长度方法。
你的问题是 length
只是一个属性。这意味着它在定义时收到一个值,并保留该值直到再次分配它。
但是 Python 有一个概念可以用属性做你想做的事:
class Deck():
def __init__(self):
# Create an empty deck and fill it with the available cards
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append(Card(suit,rank))
@property
def length(self):
return len(self.cards)
def deal_top_card (self):
self.cards.pop(0)
一个属性作为一个特殊的成员,每次使用的时候实际执行一个方法。您现在可以成功使用:
deck = Deck()
# Removing Three cards one after the other
deck.deal_top_card()
deck.deal_top_card()
deck.deal_top_card()
print(f"Length according to length attribute = {deck.length}")
print(f"Length of the list of cards = {len(deck.cards)}")
并按预期获得:
Length according to length attribute = 3
Length of the list of cards = 3
顺便说一句,属性比那个更强大,并且可以在分配给或删除时调用其他方法。阅读 https://docs.python.org/3/library/functions.html#property 了解更多...
我正在为纸牌游戏编写代码 'War'。在定义“Deck”class 时,我定义了一个属性“self.cards”,它给出了一副纸牌中当前所有纸牌的列表。我还定义了一个属性“self.length”,它应该给出“self.cards”属性的长度。
但是,当我使用 表达式 deck.length
时,它 returns 一个固定值 ,即使牌组中的牌也不会改变("self.cards") 是 removed/added。另一方面,当我使用 表达式 len(deck.cards)
时,它 returns 所需的输出 (即甲板的更新大小)。
代码为:
# I've used only two suits and three ranks to explain this problem
suits = ('Hearts','Spades')
ranks = ('Queen','King','Ace')
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
class Deck():
def __init__(self):
# Create an empty deck and fill it with the available cards
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append(Card(suit,rank))
self.length = len(self.cards)
def deal_top_card (self):
self.cards.pop(0)
deck = Deck()
# Removing Three cards one after the other
deck.deal_top_card()
deck.deal_top_card()
deck.deal_top_card()
print(f"Length according to length attribute = {deck.length}")
print(f"Length of the list of cards = {len(deck.cards)}")
上面代码的输出是:
Length according to length attribute = 6
Length of the list of cards = 3
您只是更新了 init() 方法中的 self.length。因此它不会在您每次弹出卡片时自行更新。 Init 仅在您创建对象时调用一次。您应该添加:
def deal_top_card (self):
self.cards.pop(0)
self.length = len(self.cards)
每次出卡更新长度
At 属性不会自行更新。看起来你想要一个 属性 或一个方法。
A 属性 是您想要访问 length
时要使用的东西,就好像它是一个属性一样。它还可以让您控制如果某些代码想要覆盖长度的值会发生什么:
class Deck:
....
@property
def length(self):
return len(self.cards)
...
print(f"Length according to length property = {deck.length}")
一个方法类似,但你显式调用它:
class Deck:
....
def length(self):
return len(self.cards)
...
print(f"Length according to length method = {deck.length()}")
最后,你可以定义魔术__len__
并调用len(deck)
,因为长度的概念适用于Python中的许多类型。
此外,您可能会认为 Deck
是一个与“卡片序列”非常相似的概念,因此将其作为 list
的子类可能有意义,在这种情况下您根本不需要定义长度方法。
你的问题是 length
只是一个属性。这意味着它在定义时收到一个值,并保留该值直到再次分配它。
但是 Python 有一个概念可以用属性做你想做的事:
class Deck():
def __init__(self):
# Create an empty deck and fill it with the available cards
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append(Card(suit,rank))
@property
def length(self):
return len(self.cards)
def deal_top_card (self):
self.cards.pop(0)
一个属性作为一个特殊的成员,每次使用的时候实际执行一个方法。您现在可以成功使用:
deck = Deck()
# Removing Three cards one after the other
deck.deal_top_card()
deck.deal_top_card()
deck.deal_top_card()
print(f"Length according to length attribute = {deck.length}")
print(f"Length of the list of cards = {len(deck.cards)}")
并按预期获得:
Length according to length attribute = 3
Length of the list of cards = 3
顺便说一句,属性比那个更强大,并且可以在分配给或删除时调用其他方法。阅读 https://docs.python.org/3/library/functions.html#property 了解更多...