python:实例属性的行为类似于类属性

时间:2018-11-04 20:07:06

标签: python oop instance python-3.6 class-attributes

[[我刚开始学习Python,这也是我关于Stack Overflow的第一篇文章。我在这里和其他地方广泛寻求解决方案,但没有成功。很抱歉,我不得不粘贴大量代码来演示我的问题,我确实忽略了所有不相关的内容。]

因此,我正在进行Udemy“完成Python训练营”并陷入Milestone Project 2(设计21点游戏)中。就我所知,问题在于“手”是“玩家”类的一个属性,应该是一个实例属性,但是却像一个类的属性。因此,当创建具有X个玩家的游戏时,并不是每个玩家最终都握着发给他们的两张牌,而是所有玩家最终都拥有发给任何玩家的所有卡(2 * X)。

下面的代码和输出。我正在运行python 3.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,则该变量也已被修改且与玩家的手相同。因此,这不仅不能解决我原来的问题(所有玩家最终仍然握着同一只手),而且似乎发生了某种反向分配,并且空手的更改方式与玩家的手相同。我知道没有这样的事情,但是我无法弄清楚这里到底发生了什么。

再次感谢您提供任何线索。

0 个答案:

没有答案