Python 属性错误 : type object 'x' has no attribute 'x'

标签 python debugging

我目前正在用 Python 开发一个简单的基于文本的游戏,只是为了练习 Python 和面向对象的编程,但我遇到了这个错误,它告诉我“LargeManaPotion”没有属性“name”,当我可以看到它确实如此,并且它的声明方式与工作正常的“SmallManaPotion”完全相同。我假设这是我只是忽略的一些愚蠢的错误,但会感谢您的帮助。此外,当我在 player.inventory 函数中打印玩家的库存时,程序会打印出药水,所以我不确定为什么它在 trade 函数中不起作用。无论如何,这是相关的代码。提前致谢。

class ManaPotion:
    def __init__(self):
        raise NotImplementedError("Do not create raw ManaPotion objects.")

    def __str__(self):
        return "{} (+{} Mana)".format(self.name, self.mana_value)


class LargeManaPotion(ManaPotion):
    def __init__(self):
        self.name = "Large Mana Potion"
        self.mana_value = 45
        self.value = 40


class SmallManaPotion(ManaPotion):
    def __init__(self):
        self.name = "Small Mana Potion"
        self.mana_value = 15
        self.value = 10

如您所见,它与 SmallManaPotion 相同。 这是导致错误的函数。

class TraderTile(MapTile):
def intro_text(self):
    return "A frail not-quite-human, not-quite-creature squats in the corner " \
           "\nclinking his gold coins together. \nHe looks willing to trade."

def __init__(self, x, y):
    self.trader = npc.Trader()
    super().__init__(x, y)

def trade(self, buyer, seller):
    for i, item in enumerate(seller.inventory, 1):
#the line below here is where I'm getting the error.
        print("{}. {} - {} Gold".format(i, item.name, item.value))
    while True:
        user_input = input("Choose an item or press Q to exit: ")
        if user_input in ['q', 'Q']:
            return
        else:
            try:
                choice = int(user_input)
                to_swap = seller.inventory[choice - 1]
                self.swap(seller, buyer, to_swap)
            except ValueError:
                print("Invalid choice!")

def swap(self, seller, buyer, item):
    if item.value > buyer.gold:
        print("That's too expensive.")
        return
    seller.inventory.remove(item)
    buyer.inventory.append(item)
    seller.gold = seller.gold + item.value
    buyer.gold = buyer.gold - item.value
    print("Trade complete!")

def check_if_trade(self, player):
    while True:
        print("\n\nGold: {} \nWould you like to (B)uy, (S)ell, or (Q)uit?".format(player.gold))
        user_input = input()
        if user_input in ['Q', 'q']:
            return
        elif user_input in ['B', 'b']:
            print("\n\nGold: {} \nHere's whats available to buy: ".format(player.gold))
            self.trade(buyer=player, seller=self.trader)
        elif user_input in ['S', 's']:
            print("\n\nGold: {} \nHere's what's available to sell: ".format(player.gold))
            self.trade(buyer=self.trader, seller=player)
        else:
            print("Invalid choice!")

然而,这个函数调用了 LargeManaPotion 而没有任何错误。

def print_inventory(self):
    print("Inventory:")
    for item in self.inventory:
        print('* ' + str(item))
    print("* Gold: {}".format(self.gold))
    best_weapon = self.most_powerful_weapon()
    print("Your best weapon is your {}".format(best_weapon))

错误和堆栈跟踪:

Choose an action: 
i: Print inventory
t: Trade
n: Go north
s: Go south
w: Go west
m: Replenish Mana
Action: t


Gold: 33 
Would you like to (B)uy, (S)ell, or (Q)uit?
>>>b

Gold: 33 
Here's whats available to buy: 
1. Crusty Bread - 12 Gold
2. Crusty Bread - 12 Gold
3. Crusty Bread - 12 Gold
4. Healing Potion - 60 Gold
5. Healing Potion - 60 Gold
6. Small Mana Potion - 10 Gold
7. Small Mana Potion - 10 Gold

Traceback (most recent call last):

File "/Users/Cpt_Chirp/Documents/Escape/game.py", line 74, in <module>
play()

File "/Users/Cpt_Chirp/Documents/Escape/game.py", line 17, in play
choose_action(room, player)

File "/Users/Cpt_Chirp/Documents/Escape/game.py", line 30, in choose_action
action()

File "/Users/Cpt_Chirp/Documents/Escape/player.py", line 112, in trade
room.check_if_trade(self)

File "/Users/Cpt_Chirp/Documents/Escape/world.py", line 127, in check_if_trade
self.trade(buyer=player, seller=self.trader)

File "/Users/Cpt_Chirp/Documents/Escape/world.py", line 96, in trade
print("{}. {} - {} Gold".format(i, item.name, item.value))
AttributeError: type object 'LargeManaPotion' has no attribute 'name'

Process finished with exit code 1

最佳答案

我不相信你提供了正确的代码,但你提供的代码足以确定这里发生了什么

a = list()
b = list
a.append(1)
b.append(1)

其中哪一个会引发错误?显然,附加到 b。虽然“list”类型的对象有一个方法“append”,但基类“Type List”没有。

在某处,您已将类型 LargeManaPotion 分配给一个变量,并试图从中访问字段 name。但是类型本身没有那些字段。你可以这样做的原因是因为在 python 中,类是一流的对象,可以像任何其他对象一样传递


让我们看看更接近您的实时代码的东西

class Pot(object):
    def add(self):pass

pots = [Pot(), Pot(), Pot(), Pot(), Pot]
for pot in pots: pots.add()

现在问题出在哪里?它们都是 Pot 的实例,不是吗?为什么只有最后一个引发 AttributeError?

当然,因为它们并不完全相同。前 4 项是 Pot 类的实例。它们从方法 __new__ 返回,该方法在类 type Pot 中定义,当我在变量名称后使用“括号表示法”时调用该类。在运行时,python 不知道变量“Pot”是什么。它恰好是一个类型变量,谁的调用生成一个实例对象。

最后一项是类“type Pot”的一个实例。它不是锅。它是一种类型。它的 __class__ 属性不是 Pot。它的 __class__ 属性是 type 类型用于生成实例。向类型“添加”是没有意义的。


假设您在现实生活中喝过药水。你可以用药水做事。你可以喝它们。您可以检查它们的沸点(如果它们有标签,或者可能通过科学)。

相反,假设您手头有药水的配方。你说:“喝食谱”。 “食谱的沸点是多少”。宇宙正在回应:“那是未定义的”。你的意思是看药水。相反,您查看了它的配方。与所有 OO 隐喻一样,这个隐喻是不完整的。补充阅读:

关于Python 属性错误 : type object 'x' has no attribute 'x' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36758097/

相关文章:

java - 这怎么不是 Java 可见性违规

python - 如何使用 Python 中看似有效的 s 表达式修复解析错误?

python - 在 Tensorflow 2.X 中测量 TFLite 模型的触发器

python - matplotlib 图例中的下划线文本

php - 如何在 PHP 中获取有用的错误消息?

Eclipse Debug模式不突出显示,跳转到行

调试 polymer 纸元素

python - Python RuntimeError : failed to find interpreter for Builtin discover of python_spec ='ackages.venvs/lpthw'

python - 如何获取关键词前面的数字?

php - print_r 的替代方案(仅显示最多 2 3 个键)