【问题标题】:Passing class instance reference to functions called in class definition in Python将类实例引用传递给 Python 中类定义中调用的函数
【发布时间】:2013-09-05 15:35:00
【问题描述】:

我正在尝试制作一个基本的纸牌游戏,为了跟踪轮到谁,我决定制作一个游戏类,每个实例都是一个单独的游戏。然后当游戏实例被初始化时,它也会初始化玩家对象和套牌和卡片对象,并将它们绑定到该游戏对象。为此,我尝试将游戏对象“self”传递给初始化其他对象的函数,以便它们可以引用回游戏对象。

这没有奏效。 编辑:错误是 NameError:未定义全局名称“游戏”

这个想法是完全不可能/不道德/有史以来最糟糕的事情,还是实现我的目标的完全可行的方式,但我只是错误地实施它?

整个代码都在最后,但是一个精简的版本有望说明场景——或者至少足以回答核心问题——以一种不太复杂的方式:

from collections import deque
from random import shuffle

DECK = {"value_range": (1, 6),
    "black_multiple": 2,
    "red_multiple": 2,
    "dead": 12}

class Game:
    """A game instance."""
    def __init__(self, deck=DECK):
        self.deck = Deck(self, **deck)
        self.deck.shuffle()   

class Deck:
    def __init__(self, game, value_range, black_multiple, red_multiple, dead):
        self.deck = deque()
        for value in range(*value_range):
            for i in range(black_multiple):
                self.deck.append(Card(game, value, "Black"))
            for i in range(red_multiple):
                self.deck.append(Card(game, value, "Red"))
        for i in range(dead):
            self.deck.append(Card(game))
    def shuffle(self):
        shuffle(self.deck)
    def draw(self):
        return self.deck.popleft()

这里是完整的(未完成的)代码,如果信息不够的话:

from collections import deque
from random import shuffle

DECK = {"value_range": (1, 6),
        "black_multiple": 2,
        "red_multiple": 2,
        "dead": 12}

class Game:
    """A game instance."""
    def __init__(self, player_names=["Simon", "Will"], start_cards=2,
                 deck=DECK):
        self.deck = Deck(self, **deck)
        self.deck.shuffle()
        self.players = deque()
        for name in player_names:
            self.players.append(Player(self, name))
        for player in self.players:
            player.draw(start_cards)
    def lose(self, player):
#        print(player.name + "loses.")
        pass
    def new_turn(self):
        self.players.rotate(-1)
    def get_active(self):
        return self.players[0]
    def get_passive(self):
        return list(self.players)[1:]

class Card:
    """A card instance.

    Black cards get an extra method! Dead cards have value and colour False."""
    def __init__(self, game, value=False, colour=False):
        self.value = value
        self.colour = colour
        def get_value(self):
            return self.value
        def get_colour(self):
            return self.colour
        if self.colour == "Black":
            def action(self, target):
                active = game.get_active()
                responders = game.get_passive()
                for responder in responders:
                    if responder.respond(self.value) == False:
                        continue
                    else:
                        if target == active:
                            target = responder
                        else:
                            target = active
                        break
                target.draw(self.value)

class Player:
    def __init__(self, game, name):
        self.name = name
        self.hand = {}
    def draw(self, value):
        for i in range(value):
            try:
                draw_card = game.deck.draw()
            except IndexError:
                game.lose(self)
                break
            else:
                self.hand.append(draw_card)
                continue
    def get_hand(self):
        return self.hand

class Deck:
    def __init__(self, game, value_range, black_multiple, red_multiple, dead):
        self.deck = deque()
        for value in range(*value_range):
            for i in range(black_multiple):
                self.deck.append(Card(game, value, "Black"))
            for i in range(red_multiple):
                self.deck.append(Card(game, value, "Red"))
        for i in range(dead):
            self.deck.append(Card(game))
    def shuffle(self):
        shuffle(self.deck)
    def draw(self):
        return self.deck.popleft()

感谢您抽出宝贵时间阅读本文!我之前没有做过太多正式的编码培训/练习,所以我试图通过反复试验/PyDocs 来学习 Python。

【问题讨论】:

  • “这不起作用”——你能说得更具体些吗?你从你的程序中看到了什么行为,你期望什么行为?有时会有所帮助的另一件事是尝试将其归结为一个非常小的测试程序,您认为该程序应该以某种方式运行,并验证您对该语言的心理模型是否正确。
  • 另外,在方法、函数和类之间使用换行符。

标签: python class oop instance self


【解决方案1】:

你正在做的应该没问题。在DeckPlayer__init__ 方法中,您应该存储对game 的引用

def __init__(self, game, *args):
    self.game = game

你现在没有这样做,所以我不知道你以后会如何引用这个游戏。

例如,在播放器的draw 方法中,您执行game.lose()。在 __init__ 方法中将它分配给 self 之后,它必须是 self.game.lose()

【讨论】:

  • 啊,谢谢!有道理,应该想到的。在清除了其他一些仅在更正后才浮出水面的小点(尝试附加到集合中)之后,它现在可以完美运行了。我花了一天的大部分时间来努力完成这项工作,现在我松了一口气。
  • 当你刚开始时,这是一个简单的误解。您可能想阅读有关 Python 作用域和命名空间的信息:docs.python.org/2/tutorial/… 以真正了解正在发生的事情。但是,如果您刚刚开始,那么这可能会有点令人困惑!没有胜利:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多