Python AttributeError: type object 'x' has no attribute 'x'
<p>I'm currently working on a simple text-based game in Python just to practice python and object-oriented programming but I'm running into this error where it tells me that 'LargeManaPotion' has no attribute 'name' when I can see that it does, and it is declared the exact same way as 'SmallManaPotion' which works just fine. I'm assuming it's some stupid mistake that I'm just overlooking or something but would appreciate the help.  Also, the program will print the potion just fine when I print the inventory of the player in the player.inventory function so I'm not sure why it doesn't work with within the trade function.  Anyways, here is the relevant code. Thanks in advance.</p>

<pre><code>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
</code></pre>

<p>As you can see it is identical to the SmallManaPotion.
Here is the function which causes the error.</p>

<pre><code>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 &gt; 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!")
</code></pre>

<p>However, this function calls LargeManaPotion but without any errors.</p>

<pre><code>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))
</code></pre>

<p>Error and stacktrace:</p>

<pre><code>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?
&gt;&gt;&gt;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 &lt;module&gt;
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
</code></pre>