title: Python AttributeError: type object 'x' has no attribute 'x'
body: <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>