Programming a function that saves and returns values in python
<p>I am currently experimenting with Python and programming a little text-adventure. In my game the player has certain properties like hp, attack damage and inventory slots for items.
I want to be able to call these properties from everywhere in my code. For that I created a function that receives three values: </p>

<p>"edit": to specify if a variable should be edited</p>

<p>"info_id": to specify which variable should be accessed</p>

<p>"value": the new value for the variable</p>

<p>This is what it looks like in my code:</p>

<pre><code>def player_info(edit, info_id, value):

  if edit == 1:
  ##function wants to edit value
      if info_id == 1:
          player_hp = value
          print ("Assigned hp to: ", player_hp) 
          ##the "prints" are just to check if the asignments work -&gt; they do
          return player_hp

      elif info_id == 2:
          player_attack = value
          print ("Assigned attack to: ", player_attack)
          return player_attack
      elif info_id == 3:
          item_1 = value
          return item_1
      elif info_id == 4:
          item_2 = value
          return item_2
       elif info_id == 5:
          item_3 = value

  elif edit == 0:
  ##function wants to retrieve value
      if info_id == 1:
          return player_hp
      elif info_id == 2:
          return player_attack
      elif info_id == 3:
          return item_1
      elif info_id == 4:
          return item_2
      elif info_id == 5:
          return item_3
</code></pre>

<p>There are actually 10 item slots (going up to info_id==13) but they are all the same anyway.</p>

<p>I define all variables at the beginning of my code:</p>

<pre><code>  player_info(1,1,20)
  player_info(1,2,5)
  n=3
  while n&lt;=13:
      player_info(1,n,0)
      n=n+1
##items are not fully implemented yet so I define the item slots as 0
</code></pre>

<p>The definition works, I can tell because of the control "print" I implemented in the code. Still when I call a variable, e.g. the health like this:</p>

<pre><code>player_info(0,1,0)
</code></pre>

<p>I get an error:</p>

<pre><code>local variable 'player_hp' referenced before assignment
</code></pre>

<p>Does the function not save the variable properly? Or what is the problem?</p>

<p><strong>Is there a better way to save variables? Are global variables the way to go in this case?</strong></p>

<p>Thanks for the help!</p>

<p>You asked, "<strong>Does the function not save the variable properly?</strong>"</p>

<p>In general, <strong>Python functions do not save their state</strong>. The exception is functions that use the <code>yield</code> statement. If you write a function like this</p>

<pre><code>def save_data(data):
    storage = data
</code></pre>

<p>and call it like this</p>

<pre><code>save_data(10)
</code></pre>

<p>you will not be able to get the value of <code>storage</code> later. In Python, if you need to save data and retrieve it later, you would normally use <a href="https://docs.python.org/2.7/tutorial/classes.html" rel="nofollow"><code>classes</code></a>.</p>

<p>Python <code>classes</code> allow you do do things like this:</p>

<pre><code>class PlayerData(object):
    def __init__(self, hp=0, damage=0):
        self.hp = hp
        self.damage = damage
        self.inventory = list()
        self.max_inventory = 10

    def add_item(self, item):
        if len(self.inventory) &lt; self.max_inventory:
            self.inventory.append(item)

    def hit(self, damage):
        self.hp -= damage
        if self.hp &lt; 0:
            self.hp = 0

    def attack(self, other):
        other.hit(self.damage)

if __name__ == '__main__':
    player1 = PlayerData(20, 5)
    player2 = PlayerData(20, 5)
    player1.attack(player2)
    print player2.hp
    player1.add_item('sword')
    player1.add_item('shield')
    print player1.inventory
</code></pre>

<p><strong>Output</strong></p>

<pre><code>15
['sword', 'shield']
</code></pre>

<p>This really only scratches the surface of how to use <code>classes</code>. In a more complete implementation, you might have an <code>Item</code> base class. Then you might create <code>Sword</code> and <code>Shield</code> classes that inherit from <code>Item</code>.</p>

python function variables save call