Python: can't instantiate my object from inside another object: 'global name not defined'
<p>Hi all and thanks in advance for any help. </p>

<p>I am learning Python and working on a Zork style adventure game to practise.</p>

<p>Once I've defined classes my first actual instruction is</p>

<pre><code>ourGame = Game('githyargi.txt')
</code></pre>

<p>where githyargi.txt is a file containing all the game's strings. method Game.parseText() works as documented.</p>

<p>Traceback shows the problem:</p>

<pre><code>Traceback (most recent call last):
  File "githyargi.py", line 237, in &lt;module&gt;
    ourGame = Game('githyargi.txt')
  File "githyargi.py", line 12, in __init__
    self.scenes[0] = Start()
  File "githyargi.py", line 166, in __init__
    for string in ourGame.strings['FIRST']:
NameError: global name 'ourGame' is not defined
</code></pre>

<p>If I do <code>ourGame.scenes[0] = Start()</code> from the execution block it works great- no name error, and <code>self.scenes[0].flavStr</code> gets filled up with the appropriate flavour text. However I want to create a method <code>Game.makeScenes()</code> that will create all the scenes in the game and store them in list <code>ourGame.scenes</code>. Why can't the <strong>init</strong> of Start() see ourGame.strings when instantiated from the <strong>init</strong> of Game(), when it can see the same dict when instantiated from the execution block?</p>

<pre><code>class Game(object):

    def __init__(self, filename):
        '''creates a new map, calls parseText, initialises the game status dict.'''
        self.strings = self.parseText(filename)
        self.sceneIndex = 0
        self.scenes = []
        self.scenes[0] = Start()
        self.status = {
            "Health": 100,
            "Power": 10,
            "Weapon": "Unarmed",
            "Gizmo": "None",
            "Turn": 0,
            "Alert": 0,
            "Destruct": -1
            }

    def parseText(self, filename):
        '''Parses the text file and extracts strings into a dict of
        category:[list of strings.]'''
        textFile = open(filename)
        #turn the file into a flat list of strings and reverse it
        stringList = []; catList = [] ; textParsed = {}
        for string in textFile.readlines():
            stringList.append(string.strip())
        stringList.reverse()

        #make catList by popping strings off stringList until we hit '---'
        for i in range(0, len(stringList)):
            string = stringList.pop()

            if string == '---':
                break
            else:
                catList.append(string)

        #Fill categories
        for category in catList:
            newList = []
            for i in range(0, len(stringList)):
                string = stringList.pop()

                if string == '---':
                    break
                else:
                    newList.append(string)

            textParsed[category] = newList

        return textParsed

class Scene(object):

    def __init__(self):
        '''sets up variables with null values'''
        self.sceneType = 'NULL'
        self.flavStr = "null"
        self.optStr = "null"
        self.scenePaths = []

class Start(Scene):

    def __init__(self):
        self.flavStr = ""
        for string in ourGame.strings['FIRST']:
            self.flavStr += '\n'
            self.flavStr += string
        self.optStr = "\nBefore you lies a dimly lit corridor. (1) to boldly go."
        self.scenePaths = [1]
</code></pre>

<p>It's a timing thing. When you do</p>

<pre><code>ourGame = Game('githyargi.txt')
</code></pre>

<p>Then first the Game instance is created, and only then is it assigned to ourGame.</p>

<p>Instead, pass the Game to use to the constructor of Scene, and pass <code>self</code> so it becomes something like</p>

<pre><code>self.scenes.append(Start(self))
</code></pre>

<p>Note that you also can't do <code>scenes = []</code> and then set <code>scenes[0]</code> on the next line -- an empty list doesn't have an element 0.</p>

python nameerror