寻求有关如何防止Python中无情的“NameErrors”的一般建议

时间:2013-05-27 10:34:05

标签: python namespaces function

我有一个问题,我确信在某些时候,每个中级Python程序员都会想到这个问题:也就是说,如何修复/阻止/避免/解决那些永远存在且同样令人沮丧的问题{ {1}}。我不是在谈论实际错误(比如拼写错误等),而是一个基本上没有定义全局名称的奇怪问题,而实际上它是进一步定义的。无论出于何种原因,Python似乎在这个领域非常需要:每个变量绝对必须要在上面定义并且只在任何引用它的东西之上(或者看起来如此)。

例如:

NameErrors

让Python给我这个:

condition = True

if condition == True:
    doStuff()

def doStuff():
    it_worked = True

然而,WAS定义了名称,而不是Python显然想要它的位置。所以对于一个像Traceback (most recent call last): File "C:\Users\Owner\Desktop\Python projects\test7.py", line 4, in <module> doStuff() NameError: name 'doStuff' is not defined 这样俗气的小功能来说,这没什么大不了的。只需将功能剪切并粘贴到满足系统对特定订单要求的区域即可。但是当你尝试用它来实际设计一些东西时,它几乎不可能组织代码(我必须“解组”大量的代码来容纳这个bug)。我从来没有遇到过我写过的任何其他语言的问题,所以它似乎特定于Python ...但无论如何我在文档中研究了这个并且没有找到任何解决方案(甚至是潜在的导致可能的解决方案)所以我会感谢任何提示,技巧,解决方法或其他建议。

它可能就像学习特定的组织结构一样简单(比如某种“Pythonic”和解决bug的非常具有战略性的方法),或者只是使用了很多doStuff()语句,所以它会更容易按特定顺序组织那些将阻止系统起作用的......

5 个答案:

答案 0 :(得分:5)

避免在顶层编写代码(声明除外),在要直接执行的文件中使用main()函数:

def main():
    condition = True
    if condition:
        do_stuff()

def do_stuff():
    it_worked = True

if __name__ == '__main__':
    main()

这样您只需要确保the if..main construct跟在main()函数之后(例如将其放在文件的末尾),其余的可以是任何顺序。在main()执行时,文件将被完全解析(因此可以解析模块中定义的所有名称)。

答案 1 :(得分:2)

根据经验:对于大多数情况,首先定义所有函数,然后在代码中使用它们。

答案 2 :(得分:2)

就是这样:每个名字都必须在使用时定义。

在顶级执行的代码中尤其如此:

func()

def func():
    func2()

def func2():
    print "OK"

func()

第一个func()将失败,因为它尚未定义。

但是如果我在最后致电func(),一切都会好起来的,虽然在func2()之后定义了func()

为什么呢?因为在通话时,func2()存在。

简而言之,func()的代码说“在调用时调用被定义为func2的任何内容”。

答案 3 :(得分:2)

在Python中定义函数是一种在运行时发生的行为,而不是在编译时发生的行为。在该行为期间,编译时编译的代码将分配给函数的名称。此名称是当前范围中的变量。它可以在以后任何其他变量覆盖:

def f():
  print 42

f()  # will print 42

def f():
  print 23

f()  # will print 23

您甚至可以将其他值的函数分配给变量:

def f():
  print 42
g = 23
f()  # will print 42
g    # will print 23
f, g = g, f
f    # will print 23
g()  # will print 42

如果你说你没有用其他语言来解决这个问题,那是因为你所指的其他语言不能被解释为脚本。例如,在bash中尝试类似的事情,你会发现其他语言中的东西也可以像Python一样。

答案 4 :(得分:1)

关于这一点有几点要说:

  • 如果您的代码太复杂而无法将其整理到一个文件中,请考虑使用多个文件并将其导入一个较小的主文件
  • 我把你的功能放在一个可以工作的课堂上。例如:

    class test():
        def __init__(self):
            self.do_something()
        def do_something(self):
            print 'test'
    
  • 正如Volatility评论所说,这是解释语言的一个特征