Python学习小记(3)---scope&namespace

首先,函数里面是可以访问外部变量的

#scope.py
def scope_test():
        spam = 'scope_test spam'
        def inner_scope_test():
                spam = 'inner_scope_test spam'
                def do_local():
                        spam = 'local spam'
                def do_nonlocal():
                        nonlocal spam
                        spam = 'nonlocal spam'
                def do_global():
                        global spam
                        spam = 'global spam'
                do_local()
                print('after local assignment:', spam)
                do_nonlocal()
                print('after nonlocal assignment:', spam)
                do_global()
                print('after global assignment', spam)
        inner_scope_test()
        print('after inner_scope_test:', spam)

进行如下操作

>>> import scope
>>> scope.scope_test();\ ... print(scope.spam) after local assignment: inner_scope_test spam after nonlocal assignment: nonlocal spam after global assignment nonlocal spam after inner_scope_test: scope_test spam global spam >>> print(spam) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'spam' is not defined
  •  do_local() 对本地变量操作,并未影响外部变量
  • do_nonlocal() 似乎是对外一层的 spam 进行了操作
  • do_global() 则是对 scope.spam 进行了操作
  • 同时可以发现 spam 未定义,这是因为 function 的 global 是相对于其定义所在的模块而言的,官方文档叙述如下

    It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called.

若进行如下操作

>>> from scope import scope_test as f
>>> f()
after local assignment: inner_scope_test spam
after nonlocal assignment: nonlocal spam
after global assignment nonlocal spam
after inner_scope_test: scope_test spam
>>> print(spam)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> import scope
>>> scope.spam
'global spam'

可见即使只 from scope import scope_test as f ,执行  f() 当前命名空间仍然没有 spam ,甚至若在此时导入 scope 模块, 会发现存在 scope.spam , 可见对 f() 而言,global 仍然是相对于 scope 而言的,即使 执行 f() 时 scope 模块并没有导入,为了证明 spam 确实是在执行 f()  时才被引入的,贴上下面的代码

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import scope
>>> scope.spam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'scope' has no attribute 'spam'

还有一种情况需要说明,看下面代码

def scope_test():
        spam = 'scope_test spam'
        def inner_scope_test():
                spam = 'inner_scope_test spam'
                def do_local():
                        ##############
                        print(spam)
                        spam = 'local spam'
                        ##############
                def do_nonlocal():
                        nonlocal spam
                        spam = 'nonlocal spam'
                def do_global():
                        global spam
                        spam = 'global spam'
                do_local()
                print('after local assignment:', spam)
                do_nonlocal()
                print('after nonlocal assignment:', spam)
                do_global()
                print('after global assignment', spam)
        inner_scope_test()
        print('after inner_scope_test:', spam)        

注意区别仅在于 do_local() 函数中,在  spam = 'local spam' 前面加了一句 print(spam) ,本以为 spam 会先输出外部变量,再对本地变量赋值,但事实上被视为语法错误------先使用后定义错误

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32Type "help", "copyright", "credits" or "license" for more information.
>>> import scope
>>> scope.scope_test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "E:\Coding\Python\scope.py", line 21, in scope_test
    inner_scope_test()
  File "E:\Coding\Python\scope.py", line 15, in inner_scope_test
    do_local()
  File "E:\Coding\Python\scope.py", line 7, in do_local
    print(spam)
UnboundLocalError: local variable 'spam' referenced before assignment

猜你喜欢

转载自www.cnblogs.com/liupy/p/9921980.html