Python: 实例属性表现像类属性

2024-09-30 20:27:00 发布

您现在位置:Python中文网/ 问答频道 /正文

[我刚开始学习Python,这也是我第一篇关于堆栈溢出的文章。我在这里和其他地方广泛地寻找解决办法,但没有成功。抱歉,我必须粘贴大量代码来证明我的问题,我确实遗漏了所有不相关的内容。]

因此,我正在做我的“完整的Python训练营”,陷入了里程碑项目2(设计21点游戏)。据我所知,问题是“hand”是“Player”类的一个属性,应该是一个实例属性,但其行为类似于类属性。因此,当创建一个有X个玩家的游戏时,不是每个玩家最终都手里拿着发给他们的两张牌,而是所有玩家最终都拿着发给任何玩家的所有牌(2*X)。你知道吗

下面的代码和输出。我正在运行python3.6.0。你知道吗

非常感谢您的帮助!你知道吗

import random
from IPython.display import clear_output

def reset_usedcards():
    global usedcards 
    usedcards = []

reset_usedcards()

class Card: 

    def __init__(self, color, number):
        self.color = color
        self.number = number
        self.value = number
        self.all = (self.color, (self.number[0],self.number[1]))

    def __str__(self):
        return '%s of %s' %(self.number[0], self.color)

dummycard = Card(color='',number=(0,0))
emptyhand = [dummycard,dummycard,dummycard]

def dealacard(usedcards): #returns a randomly selected card still available from the stack
    colors = ['Hearts','Cross','Diamonds','Spades']
    numbers = [(2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10), ('J',10), ('Q',10), ('K',10), ('A',11)]

    while len(usedcards) < 52:

        dealtcard = Card(random.choice(colors), random.choice(numbers))

        if dealtcard.all in usedcards:
            pass
        else:
            usedcards.append(dealtcard.all)
            return(usedcards[-1])
            break       

    else:
        print('STACK IS GONE')

class Player: #when a new instance of the class Player is created, it automatically gets dealt two cards

    def __init__(self,name,hand=[],balance=0):
        self.name = name
        self.hand = hand
        self.balance = balance
        for i in range(0,2):
            self.hand.append(dealacard(usedcards))

    def printhand(self):
        print('Current hand:')
        print(self.hand[0])
        print(self.hand[1])
        if self.hand[2].all[0] != '':
            print(self.hand[2])
        else:
            pass

emptyplayer = Player('',emptyhand,0)

class Game: #instance of game is created with the numbers of players provided via argument. 
            #I've left out the parts of the code not relevant for this post. 

    def __init__(self,np,dealer='dealer',players=[emptyplayer]*6,bets=0):        
        self.np = np
        self.dealer = dealer
        self.players = players
        self.bets = bets

        reset_usedcards()

        for n in range (0,np):
            global tempplname
            tempplname = 'player'+str(n+1)
            self.players[n] = Player(name=tempplname)
        print(f'\nGame created with {np} players')        


    def __str__(self):
        print('Players in game:')
        for i in range (0,self.np):
            print(str(self.players[i]))
        return ''

结果:

game = Game(4) 

由4名玩家创建的游戏

str(game.players[0].hand) 

“[('Diamonds',(6,6)),('Hearts',(5,5)),('Spades',('A',11)),('Diamonds',(7,7)),('Spades',(8,8)),('Spades',(7,7)),('Diamonds',(2,2)),('Cross',(8,8))]”

编辑:我现在了解了默认参数值,并设法解决了我原来的问题。感谢那些给我指出解决办法的人。然而,我应用的解决方案中有一个可行,另一个不行,尽管我认为应该这样。(我认为这与原来的问题有关,所以我正在编辑原来的帖子,而不是发布新的问题。)

这就是有效的解决方案:

class Player():

    def __init__(self,name,hand=None,balance=0):
        self.name = name
        self.hand = hand
        if self.hand is None:
            self.hand = []
        for i in range(0,2):
            self.hand.append( dealacard(usedcards))
        self.balance = balance

。。。这是一个没有:

class Player():

    def __init__(self,name,hand=None,balance=0):
        self.name = name
        self.hand = hand
        if self.hand is None:
            self.hand = emptyhand
        for i in range(0,2):
            self.hand[i] = dealacard(usedcards)
        self.balance = balance

emptyhand基本上是在Player类之外定义的占位符:

emptyhand = [dummycard,dummycard,dummycard]

因此,如果在创建玩家后调用变量emptyhand,它也会被修改,与玩家的手牌相同。因此,这不仅不能解决我原来的问题(所有玩家最终仍然握着同一只手),似乎发生了某种反向分配,空的手被修改成和玩家的手一样的方式。我知道没有这样的事,但我不知道这里到底发生了什么。你知道吗

再次感谢你提供的线索。你知道吗


Tags: nameinselfnumberdef玩家classcolor