为什么这个变量不可见?

时间:2012-06-18 22:04:32

标签: python scope

O.K。,我来自Perl和Python,我没有太多Python经验,所以对于那些对Python更有经验的人来说,这似乎相当明显。

无论如何,我只是加载配置文件然后,作为自检,打印加载的值。代码如下:

#!/home/y/bin/python2.7
import logging
import sys
import datetime
import yaml

def main(self):
    #initialize the logger
    logger = logging.getLogger(self.granularity)
    log_fh = logging.FileHandler(filename='/home/logs/pipelineTest/pipelineTest' + datetime.datetime.now().strftime('%Y%m%d_%H%M')  + '.log', mode='w')
    logger.addHandler(log_fh)
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)-6s: %(name)s - %(levelname)s - %(message)s')
    log_fh.setFormatter(formatter)

    #read configuration file
    if sys.argv[1]:
        ymlFH = open(sys.argv[1])
    else:
        ymFH = open('/home/conf/pipelineTest/runPipeline.yml')

    confDict = yaml.load(ymlFH)

if __name__ == '__main__':
    #self-test code
    for key, value in confDict.iteritems():
      print 'Key is: ' + key + '\n'
      print 'value is: ' + confDict[key] + '\n'

我遇到的错误是:

Traceback (most recent call last):
  File "./runPipeline.py", line 30, in <module>
    for key, value in confDict.iteritems():
NameError: name 'confDict' is not defined

我将其解释为名称&#34; confDict&#34;已超出范围。我不明白为什么它超出了范围。

4 个答案:

答案 0 :(得分:6)

你的main()函数有它自己的范围 - 不仅如此,但你永远不会调用它。

我建议您从函数中返回confDict,然后在正在运行的块中执行confDict = main() - 或者,如果您不打算在多个函数中使用main()函数放置,直接放下,不要打扰功能。

答案 1 :(得分:4)

变量confDict在函数main()内定义,因此它是该函数的本地变量。 (顺便说一句,你甚至不打电话给main()。)

您可能希望将for循环从脚本末尾移动到main()函数的末尾,而是在脚本末尾调用main()

答案 2 :(得分:0)

confDict是main的本地,而在python中,函数defenition依赖于缩进。因此,当您尝试在if语句中访问它时,函数范围已结束,因为main已经结束。 (见缩进)

答案 3 :(得分:0)

并非confDict超出范围,它从未进入范围。

import ...

def main(self):
    ...

if __name__ == '__main__':
    #self-test code
    for key, value in confDict.iteritems():
      print 'Key is: ' + key + '\n'
      print 'value is: ' + confDict[key] + '\n'

在那个if __name__ == ...处,您导入了一堆名称,并定义了一个名为main的函数。变量condDict从未定义过。我不知道类似代码定义condDict的任何语言,无论...中的main填写了什么。

如果您致电 main,它会创建一个名为confDict的变量。但是,该名称将是main特定调用的本地名称,因此您无法在函数之外有意义地使用它(想象您可以; main可以被多次调用,并生成许多值{ {1}};当您在confDict之外引用confDict时,会是哪一个?)。

我建议你学习一些Python教程。如果您已经熟悉一般的编程(即Perl),那么您将会通过它们,但它们将澄清所有这些基本的基本问题,以便您可以集中精力进行编码。


顺便说一下,main作为self的参数毫无意义。删除它并使用main或使用def main():,而不是将其从def main(args)中的sys.argv中拉出来(我的偏好是后者)。