问题
This script defines a variable inside main()
, but the variable isn't available to func()
, which runs inside main()
. Why is that?
#!/usr/bin/env python3
# vars_in_func.py
# Test script for variables within a function.
def func():
print(greeting)
def main():
greeting = "Hello world"
func()
main()
Error:
Traceback (most recent call last):
File "./vars_in_func.py", line 11, in <module>
main()
File "./vars_in_func.py", line 9, in main
func()
File "./vars_in_func.py", line 5, in func
print(greeting)
NameError: name 'greeting' is not defined
If I convert the script to Python2, the error is the same, except it says global name
instead of name
.
I assume I'm just missing a key concept. I just started learning Python after learning Bash.
Edit: After reading the answers, I realized my mistake: I'm still thinking in terms of Bash, where functions either run in the same shell as the caller (with the same variables), or a subshell of the caller (inherited variables).
回答1:
greeting = None
def func():
print(greeting)
def main():
global greeting
greeting = "Hello world"
func()
main()
In your solution, greeting defined in main function is a local variable and can't be accessed outside main function. that is the reason it was giving you errors
回答2:
I don't know much about python but in general global variables need to be defined outside the scope of main but before the function you want to use them in. If you don't want to make a variable global you need to pass the variable into the function as a parameter.
回答3:
There are a lot of answers about python scoping rules, and it really matters here. But as I see your question, your misunderstanding consists in something completely different: a huge difference between defining function and calling it.
LEGB rule is important but what really matters here that: "Scopes are determined statically, they looked up dynamically!". Roughly, function knows where to look for variable (when compiled), but it does not know the variables value (before you call function).
In your case you simply call one function into the body of another function. When you call function the caller passes control to the callee (roughly, imagine this as a jump in your source code to the beginning of the function's codeblock). So when you call func
you jump into func
body. This function tries to find names: print
and greeting
(this process is called Name resolution
) it looks in local
scope, then in global
scope (the scope where it was defined, not called) and finally in builtins
. It finds only print
in builtins
. Because it did not find greeting
name, an exception NameError
is raised (exception is raised at the point where the error is detected) in your case in the place where main
called func
. And when an exception is not handled at all, the interpreter terminates execution of the program, or returns to its interactive main loop. In either case, it prints a stack backtrace, except when the exception is SystemExit
.
Hope it will clarify some points for you.
One more place to look for information: The Python Language Reference: Execution model
p.s.: the global scope
is always module
(file with code) where function was defined. It is very important to understand!!!
回答4:
In python, functions can't access any variable outside of the function unless its a parameter or is declared global
.
This should hopefully fix the issue:
greeting = None
def func():
print(greeting)
def main():
global greeting # Declaring as global means func() can access it
greeting = "Hello world"
func()
main()
来源:https://stackoverflow.com/questions/41335752/variable-not-available-to-sub-function