【问题标题】:Python: can't instantiate my object from inside another object: 'global name not defined'Python:无法从另一个对象内部实例化我的对象:“未定义全局名称”
【发布时间】:2016-09-07 09:25:59
【问题描述】:

大家好,提前感谢您的帮助。

我正在学习 Python,并正在开发一款 Zork 风格的冒险游戏以进行练习。

一旦我定义了类,我的第一条实际指令就是

ourGame = Game('githyargi.txt')

其中 githyargi.txt 是一个包含所有游戏字符串的文件。方法 Game.parseText() 的工作方式与文档一致。

Traceback 显示问题:

Traceback (most recent call last):
  File "githyargi.py", line 237, in <module>
    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

如果我从执行块中执行ourGame.scenes[0] = Start(),它会很好地工作- 没有名称错误,并且self.scenes[0].flavStr 会被适当的风味文本填满。但是我想创建一个方法Game.makeScenes(),它将创建游戏中的所有场景并将它们存储在列表ourGame.scenes中。为什么Start()的init从Game()的init实例化时看不到ourGame.strings,而从执行实例化时却可以看到相同的dict屏蔽?

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]

【问题讨论】:

  • 那将是self.strings['FIRST']
  • 首先执行Game()构造函数中的所有代码,然后将结果赋值给ourGame。但是您尝试在构造函数内部使用ourGame。看看你发布的代码,是的,在Start 范围内的任何地方都没有定义ourGame
  • 感谢大家的帮助。 =)
  • 好悲痛。嘿,如果您也正在学习编码并希望看到自己进步的证据,只需回顾一下您在 18 个月前左右编写的代码!真是一团糟哈哈。 =)

标签: python nameerror


【解决方案1】:

这是一个时间问题。当你这样做时

ourGame = Game('githyargi.txt')

然后首先创建 Game 实例,然后才将其分配给 ourGame。

相反,将 Game 传递给 Scene 的构造函数,并传递 self 使其变为类似

self.scenes.append(Start(self))

请注意,您也不能先进行scenes = [],然后在下一行设置scenes[0]——空列表没有元素0。

【讨论】:

  • 没有像依赖逻辑那样真正计时......
  • 两个 bug 被压扁了一个 - 谢谢 Remco。
  • 根据您的建议,我创建了一个新方法 - Game.makeScenes(x),它将 x 个场景附加到 ourGame.scenes。效果很好。谢谢!
  • @V.G 你应该明确地传递依赖而不是依赖隐式定义的全局变量......
  • @deceze 我现在在我的孩子班上这样做 - 例如super(Corridor, self).__init__() 将继承的属性向下传递。我不确定这是否是你的意思——我仍然处于学习曲线的一部分,我不是 100% 知道如何称呼所有东西,因此寻求帮助仍然是一门不精确的科学,哈哈。
猜你喜欢
  • 1970-01-01
  • 2021-07-31
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多