3

I have a question that I am sure has been on the mind of every intermediate-level Python programmer at some point: that is, how to fix/prevent/avoid/work around those ever-so-persistent and equally frustrating NameErrors. I'm not talking about actual errors (like typos, etc.), but a bizarre problem that basically say a global name was not defined, when in reality it was defined further down. For whatever reason, Python seems to be extremely needy in this area: every single variable absolutely positively has to hast to be defined above and only above anything that refers to it (or so it seems).

For example:

condition = True

if condition == True:
    doStuff()

def doStuff():
    it_worked = True

Causes Python to give me this:

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

However, the name WAS defined, just not where Python apparently wanted it. So for a cheesy little function like doStuff() it's no big deal; just cut and paste the function into an area that satisfies the system's requirement for a certain order. But when you try to actually design something with it it makes organizing code practically impossible (I've had to "un-organize" tons of code to accomodate this bug). I have never encountered this problem with any of the other languages I've written in, so it seems to be specific to Python... but anyway I've researched this in the docs and haven't found any solutions (or even potential leads to a possible solution) so I'd appreciate any tips, tricks, workarounds or other suggestions.

It may be as simple as learning a specific organizational structure (like some kind of "Pythonic" and very strategic approach to working around the bug), or maybe just use a lot of import statements so it'll be easier to organize those in a specific order that will keep the system from acting up...

4

5 回答 5

5

Avoid writing code (other than declarations) at top-level, use a main() function in files meant to be executed directly:

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

def do_stuff():
    it_worked = True

if __name__ == '__main__':
    main()

This way you only need to make sure that the if..main construct follows the main() function (e.g. place it at the end of the file), the rest can be in any order. The file will be fully parsed (and thus all the names defined in the module can be resolved) by the time main() is executed.

于 2013-05-27T10:48:18.240 回答
2

As a rule of thumb: For most cases define all your functions first and then use them later in your code.

于 2013-05-27T10:41:40.853 回答
2

It is just the way it is: every name has to be defined at the time it is used.

This is especially true at code being executed at top level:

func()

def func():
    func2()

def func2():
    print "OK"

func()

The first func() will fail, because it is not defined yet.

But if I call func() at the end, everything will be OK, although func2() is defined after func().

Why? Because at the time of calling, func2() exists.

In short, the code of func() says "Call whatever is defined as func2 at the time of calling".

于 2013-05-27T10:46:36.657 回答
2

In Python defining a function is an act which happens at runtime, not at compile time. During that act, the code compiled at compile time is assigned to the name of the function. This name then is a variable in the current scope. It can be overwritten later as any other variable can:

def f():
  print 42

f()  # will print 42

def f():
  print 23

f()  # will print 23

You can even assign functions like other values to variables:

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

When you say that you didn't come across this in other languages, it's because the other languages you are referring to aren't interpreted as a script. Try similar things in bash for instance and you will find that things can be as in Python in other languages as well.

于 2013-05-27T11:23:01.857 回答
1

There are a few things to say about this:

  • If your code is so complex that you can't organize it in one file, think about using many files and import them into one smaller main file
  • I you put your function in a class it will work. example:

    class test():
        def __init__(self):
            self.do_something()
        def do_something(self):
            print 'test'
    
  • As said in the comment from Volatility that is an characteristic of interpreted languages

于 2013-05-27T10:45:10.837 回答