简体   繁体   English

在方法参数中传递类实例

[英]Passing class instance in the method argument

I am learning OOP, have hard time grasping how to different classes interact with each other. 我正在学习OOP,很难掌握不同类之间如何进行交互。 I read so many examples but majority of them show how single class works, and that's clear, I want to see how different classes to interact among themselves. 我读了很多示例,但是其中大多数显示了单个类的工作方式,很明显,我想了解不同类之间如何交互。 If someone has a good example how different classes interact it would be great. 如果某人有一个很好的例子,那么不同的类如何交互就很好。

Here I create Deck instance newDeck and then Player instance p1 . 在这里,我创建了Deck实例newDeck ,然后创建了Player实例p1 Then I do this: newCard.append(player.generateCard(newDeck)) where player is p1 , so I call Player method generateCard() and pass newDeck instance of class Deck . 然后,我执行以下操作: newCard.append(player.generateCard(newDeck))其中playerp1 ,所以我调用Player方法generateCard()并传递Deck类的newDeck实例。 Is this allowed? 可以吗?

Here I get error: 在这里我得到错误:

   File "poker.py", line 67, in startGame
    newCard.append(player.generateCard(newDeck))
AttributeError: 'str' object has no attribute 'generateCard'`

My code: 我的代码:

import random, string, sys

class Deck:
    def __init__(self):
        self.suits = ['s', 'h', 'd', 'c']
        self.ranks = ['2', '3', '4', '5', '6' ,'7', '8', '9', '10', 'J', 'Q', 'K', 'A']
        self.deck = [i+j for i in self.ranks for j in self.suits]
        random.shuffle(self.deck)

    def selectCards(self):
        self.selectedCard = self.deck.pop()
        return self.selectedCard

class Player:
    def __init__(self, amount):
        self.amount = amount
        self.card = []

    def generateCard(self, whichDeck):
        self.whichDeck = whichDeck
        holeCards = 2
        for i in range(0, holeCards):
            selCard = self.whichDeck.selectCards()
            if len(selCard) == 2:
                self.cardRank = list(selCard[0])
            else:
                self.cardRank = list('10') 
            self.cardSuit = list(selCard[-1])
            self.generatedCard = list(self.cardRank + self.cardSuit)
            self.card.append(self.generatedCard)
        return self.card 

class Game:
    def __init__(self, numPlayers, startingStack):
        self.startingStack = startingStack
        self.numPlayers = numPlayers

    def startGame(self):
        newDeck = Deck()
        playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
        currentPlayer = 0
        for player in playerList:
            player = Player(self.startingStack)
            currentPlayer += 1 
            if currentPlayer == self.numPlayers:
                break
        totalPlayers = currentPlayer
        # -------------------------- GAME STARTS ---------------------------
        newCard = []
        currentPlayer = 0
        for player in playerList:                
            newCard.append(player.generateCard(newDeck)) # ERROR IS HERE               
            if currentPlayer == self.numPlayers:
                break

def main():
    numberOfPlayers = 1
    playerStack = 100
    newGame = Game(numberOfPlayers, playerStack)    
    newGame.startGame()
if __name__ == '__main__':
    main()

You do not have any Player instances, you create list of string s: 您没有任何Player实例,您将创建string s的列表:

playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']

then in the loop you just do 然后在循环中

for player in playerList:
        player = Player(self.startingStack)
        currentPlayer += 1 
        if currentPlayer == self.numPlayers:
            break

and this local variable player is lost, it is not magically appended to your playerList 并且这个本地变量player丢失了,它没有神奇地附加到您的playerList

Simply do something like 只需做类似的事情

playerList = [ Player(self.startingStack) for _ in range(self.numPlayers) ]

instead of your loop 而不是你的循环

Your playerList object is still a list of strings. 您的playerList对象仍然是字符串列表。 Your loop: 您的循环:

for player in playerList:
    player = Player(self.startingStack)
    currentPlayer += 1 
    if currentPlayer == self.numPlayers:
        break

re-binds player to a Player() instance, but this doesn't change the playerList object . player重新绑定到Player()实例,但这不会更改playerList对象 In fact, by the time you get to the next iteration, the Player() instance is discarded again as nothing else references it. 实际上,到下一次迭代时, Player()实例将再次被丢弃,因为没有其他引用它。

The for player in playerList binds player to each string in the list in turn, but the reference does not work the other direction, player is just another Python name, another reference to the same object contained in playerList . for player in playerListfor player in playerListplayer绑定到列表中的每个字符串,但是该引用在另一个方向上无效, player 只是另一个Python名称,另一个对playerList包含的同一对象 playerList Assigning a different object to it will not also alter the list from which the strings were taken. 给它分配一个不同的对象也不会改变从中获取字符串的列表。

You probably wanted to build a new list here: 您可能想在这里建立一个新列表:

def startGame(self):
    newDeck = Deck()
    playerList = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
    players = []
    for player in playerList[:self.numPlayers]:
        player = Player(self.startingStack)
        players.append(player)
    totalPlayers = self.numPlayers
    # -------------------------- GAME STARTS ---------------------------
    newCard = []
    for player in players:           
        newCard.append(player.generateCard(newDeck))

However, you are entirely ignoring the strings in playerList here; 但是,您将完全忽略此处的playerList的字符串。 may as well just build the list without consulting those: 也可以不咨询以下人员而建立列表:

def startGame(self):
    newDeck = Deck()
    players = [Player(self.startingStack) for _ in range(self.numPlayers)]
    newCard = [player.generateCard(newDeck) for player in players]

but you don't need players then as a separate list either: 但是您也不需要players作为单独的列表:

def startGame(self):
    newDeck = Deck()
    newCard = [Player(self.startingStack).generateCard(newDeck)
               for _ in range(self.numPlayers)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM