定义为另一个列表类型的长度的类属性 类属性不会自行更新,并且始终返回相同的值



我正在为纸牌游戏"War"编写代码。在定义";甲板";类,我定义了一个属性";self.cards";其给出当前在一副牌中的所有牌的列表。我还定义了一个属性";自身长度";预计这将给出"0"的长度;self.cards";属性

但是,当我使用表达式deck.length时,它会返回一个固定值,即使移除/添加了牌组中的牌("self.cards"(,这个值也不会改变。另一方面,当我使用表达式len(deck.cards)时,它会返回所需的输出(即甲板的更新大小(。

代码为:

# 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

您的问题是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了解更多。。。

您只是在init((方法中更新self.length。因此,它并不是每次你弹出一张卡时都会更新自己。Init只在创建对象时调用一次。您应该添加以下内容:

def deal_top_card (self):
self.cards.pop(0)
self.length = len(self.cards)

每次弹出卡片时更新长度

At属性不会自我更新。看起来你想要一个属性或方法。

如果要将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方法。

相关内容

  • 没有找到相关文章

最新更新