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

#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. 《ASP.NET Core 高性能系列》关于.NET Core的部署方式

    概述,.NET Core应用程序可以创建三种类型的部署:FDD SCD FDE 框架依赖的部署(FDD).顾名思义,框架依赖的部署(FDD)依赖于目标系统上是否存在.NET Core版本.由于.NET ...

  2. 玩转Django2.0---Django笔记建站基础九(二)(Auth认证系统)

    9.4 设置用户权限 用户权限主要是对不同的用户设置不同的功能使用权限,而每个功能主要以模型来划分.以9.3节的MyDjango项目为例,在Admin后台管理系统可以查看并设置用户权限,如下图: 用户 ...

  3. windows10卸载虚拟机忘记按照步骤卸载的实际问题

    好久没有写博客了,由于太多事情,工作需要用到虚拟机,结果,虚拟机出问题,,,怎么办???我的办法就是卸载了重新安装一个,结果呢?太心急没有按照不知操作,今天弄了一下午,终于弄好了... 错误原因,用了 ...

  4. Java基础系列1:深入理解Java数据类型

    Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...

  5. Linux 高压缩率工具 XZ 压缩详解

    目录 一.XZ 基础信息 二.安装 三.详解 3.1.常用的参数 3.2. 常用命令 四.扩展 4.1.unxz 4.2.xzcat 4.3.lzma 4.4.unlzma 4.5.lzcat 一.X ...

  6. spring mvc 框架运行机制 + 数据绑定原理

    spring mvc 运行主要的组件: 1 前端控制器 (dispatchservlet) 相当于一个重要处理器,它用来调用其他功能模块来分工的效应一次请求,主要起调度的作用. 2. handler ...

  7. <状压DP>solution-POJ3311_Hie with the Pie

    Hie with the Pie Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers ...

  8. 第一篇:Vue基础

    Vue基础 渐进式JavaScript框架 通过对框架的了解与运用程度,来决定其在整个项目中的应用范围,最终可以独立以框架方式完成整个web前端项目 走进Vue 什么是Vue 渐进式JavaScrip ...

  9. Spring(五)核心容器 - 注册 Bean、BeanDefinitionRegistry 简介

    目录 前言 正文 1.BeanDefinitionRegistry 简介 2.registerBeanDefinition 方法注册 Bean 最后 前言 上篇文章我们对 BeanDefinition ...

  10. 不要被C++“自动生成”所蒙骗

    http://www.cnblogs.com/fanzhidongyzby/archive/2013/01/12/2858040.html C++对象可以使用两种方式进行创建:构造函数和复制构造函数. ...