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

#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

Python学习小记(3)---scope&namespace的更多相关文章

  1. Python学习小记(1)---import小记

    在这种目录结构下,import fibo会实际导入fibo文件夹这个module λ tree /F 卷 Programs 的文件夹 PATH 列表 卷序列号为 BC56-3256 D:. │ fib ...

  2. python学习小记

    python HTTP请求示例: # coding=utf-8 # more materials: http://docs.python-requests.org/zh_CN/latest/user/ ...

  3. Python学习小记(5)---Magic Method

    具体见The Python Language Reference 与Attribute相关的有 __get__ __set__ __getattribute__ __getattr__ __setat ...

  4. Python学习小记(4)---class

    1.名称修改机制 大概是会对形如 __parm 的成员修改为 _classname__spam 9.6. Private Variables “Private” instance variables ...

  5. Python学习小记(2)---[list, iterator, and, or, zip, dict.keys]

    1.List行为 可以用 alist[:] 相当于 alist.copy() ,可以创建一个 alist 的 shallo copy,但是直接对 alist[:] 操作却会直接操作 alist 对象 ...

  6. python 学习小记之冒泡排序

    lst =[11,22,44,2,1,5,7,8,3] for i in range(len(lst)):     i = 0     while i < len(lst)-1:         ...

  7. Python学习 Part7:类

    Python学习 Part7:类 1. 作用域和命名空间 命名空间(namespace)就是一个从名称到对象的映射. 命名空间的一些实例:内置名称集(函数,像abs(),和内置异常名称),一个模块中的 ...

  8. mongodb入门学习小记

    Mongodb 简单入门(个人学习小记) 1.安装并注册成服务:(示例) E:\DevTools\mongodb3.2.6\bin>mongod.exe --bind_ip 127.0.0.1 ...

  9. python学习笔记之module && package

    个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...

随机推荐

  1. Mysql.linux登录数据库

    //mysql -hlocalhost -uroot -p //-h数据库地址 -u用户名 -p密码 -P端口号(P大写)//-p可省略,会提示输入密码. mysql -h127. -uroot -p ...

  2. (数据科学学习手札73)盘点pandas 1.0.0中的新特性

    本文对应脚本及数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 毫无疑问pandas已经成为基于Pytho ...

  3. 获取各类前几名数据的MYSQL写法

    前几天,某在培训的朋友问我一个问题:查询每门功课成绩最好的前两名该怎么写. 这个问题虽然听起来挺简单,但是很有意思,于是我就新建了一张如下的表: stuNo为学号,stuScore为分数,course ...

  4. JZOJ4238 纪念碑

    Description 2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址. 纪念中学的土地可以看作是一个长为n,宽为m的矩形.它由n* m个1*1的 ...

  5. MYGUI3.2改造——完善windows下的文字显示

    MYGUI 3.2 是支持中文显示的——往“MyGUI_Fonts.xml”文件里添加上中文的编码范围即可,这个网上有很多. 能显示中文后,再添加中文的自动换行,这个网上有:http://blog.s ...

  6. 初入计科,首次接触C的感受

    1 你对计算机科学与技术专业了解是怎样? 答:一开始我对这个专业并无了解,觉得无非是把电脑给学透.经过一周的学习后,我深刻地感觉自己对这个专业深深的误解. 通过翻阅书籍,上网浏览相关信息,我认为该专业 ...

  7. Nginx核心模块

    error_log 语法:error_log file [ debug | info | notice | warn | error | crit ]默认值:${prefix}/logs/error. ...

  8. linux 移动复制删除

    linux下文件的复制.移动与删除命令为:cp,mv,rm一.文件复制命令cp    命令格式:cp [-adfilprsu] 源文件(source) 目标文件(destination)        ...

  9. Spring JSTL 获取后端数据失败。

    显示的jsp页面仍是${XXX}的形式. 解决方法一: 这是因为我们在web.xml中使用的是jsp1.2版本的DTD,在此版本JSTL默认不打开,我们需要手动打开,打开方法: 在相应的JSP头部加入 ...

  10. spring cloud oauth2搭建认证中心与资源中心

    一 认证中心搭建 添加依赖,如果使用spring cloud的话,不管哪个服务都只需要这一个封装好的依赖即可 <dependency> <groupId>org.springf ...