Python 基础 —— global 与 nonlocal

global

全局语句是一个适用于整个当前代码块的声明。这意味着列出的标识符将被解释为全局变量。尽管自由变量可能引用全局变量而不被声明为全局变量,但是不可能赋值给全局变量。

在全局语句中列出的名称不能在该语句之前的文本中使用相同的代码块。

全局语句中列出的名称不能被定义为形式参数,也不能定义在for循环控件目标,类定义,函数定义或导入语句中。

CPython实现细节:目前的实现并没有强制执行这两个限制,但程序不应该滥用这种自由,因为未来的实现可能会强制执行它们或者默认地改变程序的含义。
程序员注意:全局是解析器的指令。它仅适用于与全局语句同时解析的代码。特别是,提供给内置exec()函数的字符串或代码对象中包含的全局语句不会影响包含函数调用的代码块,并且包含在该字符串中的代码不受包含的代码中的全局语句的影响函数调用。这同样适用于eval()和compile()函数。

In [96]: gcount = 0
    ...: def global_test():
    ...:     print (gcount)
    ...:
    ...: def global_counter():
    ...:     global gcount
    ...:     gcount +=1
    ...:     return gcount
    ...:
    ...: def global_counter_test():
    ...:     print(global_counter())
    ...:     print(global_counter())
    ...:     print(global_counter())
    ...:

In [97]: global_counter_test()
1
2
3

In [102]: gcount = 0
     ...: def global_test():
     ...:     print (gcount)
     ...:
     ...: def global_counter():
     ...:     gcount = 0
     ...:     gcount +=1
     ...:     return gcount
     ...:
     ...: def global_counter_test():
     ...:     print(global_counter())
     ...:     print(global_counter())
     ...:     print(global_counter())
     ...:

In [103]:

In [103]:

In [103]: global_counter_test()
1
1
1

nonlocal

导致列出的标识符引用最近的封闭范围中的先前绑定的变量,而不包括全局变量。 这很重要,因为绑定的默认行为是首先搜索本地命名空间。 该语句允许封装的代码重新绑定局部范围之外的变量,除了global(module)范围。

在非本地语句中列出的名称与全局语句中列出的名称不同,它们必须在封闭的范围内引用预先存在的绑定(创建新绑定的范围无法明确确定)。

In [105]: def make_counter():
     ...:     count = 0
     ...:     def counter():
     ...:         nonlocal count
     ...:         count += 1
     ...:         return count
     ...:     return counter
     ...:
     ...: def make_counter_test():
     ...:   mc = make_counter()
     ...:   print(mc())
     ...:   print(mc())
     ...:   print(mc())
     ...:

In [106]: make_counter_test()
1
2
3

7.12. The global statement
global_stmt ::= “global” identifier (“,” identifier)*
The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

Names listed in a global statement must not be used in the same code block textually preceding that global statement.

Names listed in a global statement must not be defined as formal parameters or in a for loop control target, class definition, function definition, or import statement.

CPython implementation detail: The current implementation does not enforce the two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program.
Programmer’s note: the global is a directive to the parser. It applies only to code parsed at the same time as the global statement. In particular, a global statement contained in a string or code object supplied to the built-in exec() function does not affect the code block containing the function call, and code contained in such a string is unaffected by global statements in the code containing the function call. The same applies to the eval() and compile() functions.

7.13. The nonlocal statement
nonlocal_stmt ::= “nonlocal” identifier (“,” identifier)*
The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).

Names listed in a nonlocal statement must not collide with pre-existing bindings in the local scope.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值