Variable not available to sub-function [duplicate]

一笑奈何 提交于 2021-02-08 09:54:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!