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

#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. 20190918Java课堂记录

    1. EnumTest.java public class EnumTest { public static void main(String[] args) { Size s=Size.SMALL; ...

  2. Bug的等级程度(Blocker, Critical, Major, Minor/Trivial)及修复优先级

    Priority()和Severity(严重程度)是Bug的两个重要属性.很多新人经常混淆这两个概念. 通常,人员在提交Bug时,只定义Bug的Severity, 即该Bug的严重程度, 而将Prio ...

  3. Oracle 11g 安装过程及测试方法

    大家可以根据自己的操作系统是多少位(32位或64位)的,到官网下载相应的安装程序,如下图所示. 有一点需要注意,Oracle的安装程序分成2个文件,下载后将2个文件解压到同一目录即可.     下载完 ...

  4. Python学习,第二课 - 字符编码

    关于字符编码 python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascill) ASCII(American Standard Code for Information Inte ...

  5. 痞子衡嵌入式:知名半导体MCU大厂软件开发C代码规范

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是飞思卡尔软件开发C语言编码规范. 2020鼠年春节是个漫长的假期,痞子衡在家百无聊赖,翻出了2016年10月1日(这个时间是痞子衡正式开始 ...

  6. Docker基础内容之端口映射

    随机映射 docker run -d -P training/webapp python app.py # -P会随机映射一个 49000~49900 的端口到内部容器开放的网络端口 映射所有接口地址 ...

  7. Redis入门,Jedis和常用命令

    一.Redis简介 1.关于关系型数据库和nosql数据库 关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据     库是基于特殊的结构,并将数据存储到内存的数据库.从性 ...

  8. 工作流Activity框架入门(一)

    Activity工作流入门 1. 工作流概念 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某 ...

  9. 解决Eclipse无法安装STS

    使用Eclipse Neon安装Spring Tool Suite报错: Cannot complete the install because one or more required items  ...

  10. 《Android Studio实战 快速、高效地构建Android应用》--四、Git入门

    Git版本控制系统(VCS)是分布式的,仓库的每一个副本均包含项目的完整历史 安装Git 下载 下载地址:http://git-scm.com/downloads 选择适合自己操作系统的来下载 如果下 ...