Python 使用全局变量,为什么有的时候可以不加 global ?
类使用类方法,访问 success_list
是可以的!
from loguru import loggersuccess_list: list[float] = [1,2,3,4,5,6,7,8]
class Myclass:
def run(self):
logger.debug(success_list)
Myclass().run()
logger.debug(success_list)
运行结果:
2022-07-29 16:15:23.838 | DEBUG | __main__:run:8 - [1, 2, 3, 4, 5, 6, 7, 8]2022-07-29 16:15:23.838 | DEBUG | __main__:<module>:13 - [1, 2, 3, 4, 5, 6, 7, 8]
但是加两行代码就不行了
python">from loguru import loggersuccess_list: list[float] = [1,2,3,4,5,6,7,8]
class Myclass:
def run(self):
logger.debug(success_list)
success_list = success_list[1:]
logger.debug(success_list)
Myclass().run()
logger.debug(success_list)
运行结果:
Traceback (most recent call last): File "/Users/ponponon/Desktop/code/me/ideaboom/tools copy.py", line 12, in <module>
Myclass().run()
File "/Users/ponponon/Desktop/code/me/ideaboom/tools copy.py", line 8, in run
logger.debug(success_list)
UnboundLocalError: local variable 'success_list' referenced before assignment
主注意,报错在logger.debug(success_list)
而不是success_list = success_list[1:]
但是加上 global 又可以了!?
from loguru import loggersuccess_list: list[float] = [1,2,3,4,5,6,7,8]
class Myclass:
def run(self):
global success_list
logger.debug(success_list)
success_list = success_list[1:]
logger.debug(success_list)
Myclass().run()
logger.debug(success_list)
运行结果:
2022-07-29 16:16:33.181 | DEBUG | __main__:run:9 - [1, 2, 3, 4, 5, 6, 7, 8]2022-07-29 16:16:33.181 | DEBUG | __main__:run:11 - [2, 3, 4, 5, 6, 7, 8]
2022-07-29 16:16:33.181 | DEBUG | __main__:<module>:15 - [2, 3, 4, 5, 6, 7, 8]
为什么第一份代码可以不加 global ?
回答:
当内部作用域想修改外部作用域的变量时,就要用到 global,
如果只是访问的话,可以不用加。
回答:
可以考虑用inspect.getclosurevars
方法来看一下python对两个函数处理方式的区别。
下面用一个简单的例子连同执行结果说明一下:
>>> import inspect>>> g = 1
>>> def a():
... return g
...
>>> def b():
... g = g + 1
... return g
...
>>> inspect.getclosurevars(a)
ClosureVars(nonlocals={}, globals={'g': 1}, builtins={}, unbound=set())
>>> inspect.getclosurevars(b)
ClosureVars(nonlocals={}, globals={}, builtins={}, unbound=set())
回答:
当遇到一个名字的时候,是从当前开始向外找的。success_lines = ....
是一个 name binding operation ,相当于它会在当前层创建一个 success_lines
;这样,如果没有 global ,就找不到外层的了,想用全局的就必须 global 。但是如果没有赋值,那么当前没有这个变量,就可以找到外层的。
resolution of names
4.2.2. Resolution of names
......
When a name is used in a code block, it is resolved using the nearest enclosing scope.
......
If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block.
.....
If the global statement occurs within a block, all uses of the names specified in the statement refer to the bindings of those names in the top-level namespace.
binding of names
Names refer to objects. Names are introduced by name binding operations.
The following constructs bind names:
- formal parameters to functions,
- class definitions,
- function definitions,
- assignment expressions,
- ......
以上是 Python 使用全局变量,为什么有的时候可以不加 global ? 的全部内容, 来源链接: utcz.com/p/938557.html