2016-04-21 83 views
3

我目前正在一個簡單的基於文本的遊戲在Python只是爲了實踐python和麪向對象的編程,但我遇到了這個錯誤告訴我'LargeManaPotion'沒有屬性'name',當我看到它的確如此,並且它被聲明爲與'SmallManaPotion'完全相同的工作方式。我假設這是一個愚蠢的錯誤,我只是俯視或什麼,但會感謝幫助。此外,當我在player.inventory函數中打印播放器的庫存時,程序將打印藥水,所以我不確定它爲什麼在交易函數中不起作用。無論如何,這裏是相關的代碼。提前致謝。Python的AttributeError:類型的對象'x'沒有屬性'x'

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 
+1

請張貼錯誤消息和堆棧跟蹤。 – ozgur

回答

5

我不相信你提供了正確的代碼,但是你能提供足夠的確定怎麼在這裏

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的實例。從類type Pot中定義的方法__new__返回,當我在變量名後面使用「括號表示法」時調用該方法。在運行時,python不知道變量「Pot」是什麼。它恰好是一個類型變量,誰的調用會生成一個實例對象。

最後一項是類「鍋」的一個實例。這不是一個鍋。這是一種類型。它的__class__屬性不是Pot。它的__class__屬性是類型類型用於生成實例。 「添加」到一個類型是沒有意義的。


假設你在現實生活中有魔藥。你可以用魔藥做些事情。你可以喝它們。你可以檢查他們的沸點(如果他們有標籤,或者可能通過科學)。

取而代之,假設你有一個藥水躺在身邊。你說:「喝配方」。 「什麼是配方的沸點」。宇宙正在迴應:「那是未定義的」。你打算看一下魔藥。相反,你看它的配方。像所有的OO隱喻一樣,這個隱喻是不完整的。補充閱讀:

+0

我不確定我關注。什麼使LargeManaPotion與SmallManaPotion不同? SmallManaPotion在LargeManaPotion之前在該循環中被調用並且正常工作。實際上,如果我完全刪除LargeManaPotion,運行該程序時不會出現錯誤。 –

+0

@JameyPhillips這有幫助嗎? –

+2

哇。是的,你是完全正確的,我在Trader npc類中有一個typer,我添加了LargeManaPotion而不是LargeManaPotion()。直到我讀到你的評論,然後去仔細檢查,我才從那裏看到。我只是假設它是在LargeManaPotion初始化器中,因爲我(錯誤地)認爲其他所有東西都是一樣的。感謝您的快速響應順便說一句。 –

1

就行啦指示與評論的錯誤,請嘗試而不是調用

print(item) 

我想你可能會看到一些令人驚訝的結果。在一個提示,我做了以下內容:

>>> print(LargeManaPotion) 
<class '__main__.LargeManaPotion'> 
>>> print(LargeManaPotion()) 
Large Mana Potion (+45 Mana) 

你似乎並沒有爲你的程序的完整源(因此我無法驗證),但我懷疑你所看到的「<類。 ..「線。因爲我猜,我說你構建賣家的庫存的地方指的是類本身

LargeManaPotion 

,而不是實例化(主叫),它

LargeManaPotion() 
+0

感謝您的回覆,最終成爲問題。在我添加到NPC Trader庫存的對象列表中,我忘記將()放在LargeManaPotion()的末尾。 –

相關問題