在类中声明变量后的NameError

时间:2017-06-13 13:39:52

标签: python

我正在模拟一副卡片,其中返回draw_pile列表中的随机卡片,然后从draw_pile中删除并将其附加到discard_pile中。

class Deck:

    draw_pile = ["example_1", "example_2", "example_3"]
    discard_pile = []

    def draw(self):
        card = random.choice(draw_pile)
        draw_pile.remove(card)
        discard_pile.append(card)
        return card

example_deck = Deck()
print(example_deck.draw())

但我一直收到以下错误:

card = random.choice(draw_pile)
NameError: name 'draw_pile' is not defined"

1 个答案:

答案 0 :(得分:2)

Python类不会为查找算法创建新范围。在draw内部,当找不到draw_pile的本地定义时,Python接下来会查看下一个封闭范围,即模块级范围,而不是封闭类定义。

要访问class属性,您需要使用类名

def draw(self) :
    card = random.choice(deck.draw_pile)
    deck.draw_pile.remove(card)
    deck.discard_pile.append(card)
    return card

或通过self间接访问它;如果找不到名为draw_pile的实例属性,则Python接下来会查看self类型的类属性:

def draw(self) :
    card = random.choice(self.draw_pile)
    self.draw_pile.remove(card)
    self.discard_pile.append(card)
    return card

可以说,具体关于draw_pilediscard_pile的来源更为清晰,并直接使用类名。使用self要求您了解有关哪些类self在其MRO中的详细信息。

此外,除非deck永远不会包含多个实例,否则draw_pilediscard_pile都应该是实例变量,因此必须可以通过self访问:

class Deck :
    def __init__(self):
        self.draw_pile = ["exmample_1", "example_2", "example_3"]
        self.discard_pile = [""]

    def draw(self) :
        card = random.choice(self.draw_pile)
        self.draw_pile.remove(card)
        self.discard_pile.append(card)
        return card

example_deck = Deck()
print(Deck.draw())