Python学习小记(3)---scope&namespace,,首先,函数里面是可以


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

#scope.pydef 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 spamafter nonlocal assignment: nonlocal spamafter global assignment nonlocal spamafter inner_scope_test: scope_test spamglobal 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 spamafter nonlocal assignment: nonlocal spamafter global assignment nonlocal spamafter 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 win32Type "help", "copyright", "credits" or "license" for more information.>>> import scope>>> scope.spamTraceback (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

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

评论关闭