Python 名称空间与作用域、闭包与装饰器
Python 的名称
Python 的名称(Name)是对象的一个标识(Identifier)。我们知道,在 Python 里面一切皆对象,名称就是用来引用对象的。说得有点玄乎,我们以例子说明。
例如,在a = 2
这个语句中,2
是个存储在内存中的一个对象,名称a
则会引用2
这个对象,“引用”的含义是指可以通过名称a
来使用2
这个对象。我们可以使用id()
函数来获取对象的地址。
可以看到,两都均指向同一个对象
Python 的名称与对象
起初,名称a
引用对象2
;
然后,执行操作a = 1
,这时对象1
被创建,名称a
引用对象1,所以id(a)
和id(1)
输出相同的地址; 但是对象2没有名称引用,继而丢弃在内存空间中成为垃圾。
这个例子也展示了 Python 在执行变量的赋值时,并不会重复创建一个对象的事实。名称采用动态绑定的机制使得 Python 更加高效,同一个名称可以引用不同类型的对象。
Python 的名称空间
名称空间是名称到对象的映射。在 Python 中,名称空间采用字典来实现。Python 的名称空间包括:
- 内置名称空间,例如,内置名称空间包含 Python 的内置函数,如,
abs()
- 模块名称空间,全局名称空间,在模块内定义的名称
- 局部名称空间,例如,在函数(function)或者类(class)被调用时,其内部包含的名称
不同的名称空间内的名称不会相互冲突,即是它们采用相同的名称。这也正是名称空间的作用。
内置名称空间在 Python 解释器启动时就创建了,直到 Python 解释器退出时内置名称空间才失效。这使得我们可以在程序的任何位置使用内置名称空间内的名称,例如,id()
,print()
等函数。
模块名称空间当模块被引用时创建,直到 Python 解释器退出时模块名称空间才失效。
函数名称空间在函数被调用时创建,函数返回后失效。
Python 变量的作用域
例子
在这个例子中,名称a
在全局名称空间中,名称b
在函数outer_function
的局部名称空间,名称c
则在函数inner_func
的局部名称空间。
当我们在函数inner_func
时,c
是个局部的名称,b
是个非局部的名称,而a
则是个全局的名称。在函数inner_func
中,我们可以对c
进行读取操作和赋值操作,而只能对b
和a
进行读取操作。当对b
进行赋值时,一个新的名称将会被创建,这个新的名称处于inner_func
函数局部名称空间中。对a
进行赋值时也会在局部名称空间中创建一个新的名称。
如果想要对全局变量进行修改以便下次调用,可以用global xxx(变量名)即可。
Python 闭包
如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
在python3中,可以用nonlocal 关键字声明 一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。
闭包有啥用??!!
装饰器!!!装饰器是做什么的??其中一个应用就是,我们工作中写了一个基础平台功能,我们想让别的部门可以调用,但是原先基础平台又不允许改代码,这就是装饰器的作用
面向对象!!!经历了上面的分析,我们发现外函数的临时变量送给了内函数。大家回想一下类对象的情况,对象有好多类似的属性和方法,所以我们创建类,用类创建出来的对象都具有相同的属性方法。闭包也是实现面向对象的方法之一。在python当中虽然我们不这样用,在其他编程语言入比如avaScript中,经常用闭包来实现面向对象编程
实现单利模式!! 其实这也是装饰器的应用。单利模式毕竟比较高大,,需要有一定项目经验才能理解单利模式到底是干啥用的,我们就不探讨了。
Python 装饰器
当写完这段代码后(函数未被执行、未被执行、未被执行),python解释器就会从上到下解释代码,步骤如下:
- def w1(func): ==>将w1函数加载到内存
- @w1
- @w1就相当于 #下面定义的函数名 = w1(定义的函数名作为实参),当最下面一行 调用 f1()的函数的时候才是会去闭包里的inner函数执行相应的操作
没错,从表面上看解释器仅仅会解释这两句代码,因为函数在没有被调用之前其内部代码不会被执行。
从表面上看解释器着实会执行这两句,但是 @w1 这一句代码里却有大文章,@函数名 是python的一种语法糖。
如上例@w1内部会执行一下操作:
- 执行w1函数,并将 @w1 下面的 函数 作为w1函数的参数,即:@w1 等价于 w1(f1)
所以,内部就会去执行:
def inner:
return f1() # func是参数,此时 func 等于 f1
return inner # 返回的 inner,inner代表的是函数,非执行函数
其实就是将原来的 f1 函数塞进另外一个函数中 - 将执行完的 w1 函数返回值赋值给@w1下面的函数的函数名
w1函数的返回值是:
def inner:
return 原来f1() # 此处的 f1 表示原来的f1函数
然后,将此返回值再重新赋值给 f1,即:
新f1 = def inner:
return 原来f1()
所以,以后业务部门想要执行 f1 函数时,就会执行 新f1 函数,在 新f1 函数内部先执行验证,再执行原来的f1函数,然后将 原来f1 函数的返回值 返回给了业务调用者。
如此一来, 即执行了验证的功能,又执行了原来f1函数的内容,并将原f1函数返回值 返回给业务调用着
Python 名称空间与作用域、闭包与装饰器的更多相关文章
- python名称空间和作用域
python名称空间和作用域 名称空间 名称空间:例如a=1000,python解释器会开辟一块新的内存来存贮1000这个变量值,然后会有一个a指向这个1000,那么a存在哪里?其实他和变量值差不多, ...
- Python记录9:函数4:名称空间作用域+闭包函数+装饰器
''' 一: 名称空间namespaces 名称空间就是存放名字与值绑定关系的内存空间 二: 名称空间分为三种 内置名称空间: 1. 特点: 存放是python解释器自 ...
- Python 函数对象-函数嵌套-名称空间与作用域-闭包函数
今日内容: 1. 函数对象 函数是第一类对象: 指的是函数名指向的值可以被当中数据去使用 1.可以被引用 2.可以当做参数传给另一个函数 3.可以当做一个函数的返回值 4.可以当做容器类型的元素 2. ...
- Python名称空间与作用域
什么是名称空间? 比如下图的长方形代表内存,在这个内存里我要设置一个变量100,那么这个变量得有个门牌号,就叫他a吧,但其实变量不是这么存储的,他其实的存储方式是这样的,他会有一个名称空间,这个名称空 ...
- Python 名称空间和作用域
a = 10 # lst = [1,2,3,4] # # # 内置函数 print("你好啊,我叫赛利亚") # def chi(): a = 10 b = 20 # # # # ...
- 13、python中的函数(闭包与装饰器)
一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...
- python 生成器,迭代器,闭包,装饰器
1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...
- Python的高级特性7:闭包和装饰器
本节跟第三节关系密切,最好放在一起来看:python的高级特性3:神奇的__call__与返回函数 一.闭包:闭包不好解释,只能先看下面这个例子: In [23]: def outer(part1): ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
随机推荐
- ERROR 1130 (HY000): Host '192.168.0.190' is not allowed to connect to this MySQL serv
环境: CentOS6.2.MySQL5.1 问题描述: 在配置文件中将需要连接的MySQL的host设置为192.168.0.190(其实就是我自己的IP地址),然后运行自己的程序,结果返回MySQ ...
- form之action的绝对路径与相对路径
1.当你的form要提交到你自己的站点之外的URL的时候,就采取绝对路径: <form action="http://www.xxx.yyy:zzzz/mmm/nn/kkk.jsp&q ...
- python课文题目格式
import win32com from win32com.client import Dispatch,constants w = win32com.client.Dispatch('Word.Ap ...
- java web 自定义filter
filter顾名思义,过滤器的意思,在javaweb中的Struts就利用了这种机制去实现视图和业务分离. 这里来配置下自己的Filter来理解下Struts的内在. 在web.xml 中添加下面: ...
- Unix系统编程()发送信号的其他方式:raise和killpg
有时,进程需要向自身发送信号,raise 函数就执行了这一任务. #include <signal.h> int raise(int sig); 在单线程程序中,调用raise相当于对ki ...
- groupBox和panel
private void Form1_Load(object sender, EventArgs e) { groupBox1.Text = "信息表"; panel1.Borde ...
- sama5d36 can0 can1 测试
1 删除/bin/ip 保留/sbin/ip 2 ip link set can0 type can bitrate 125000 ip link set can1 type can bitrate ...
- lnmp服务器的目录信息
LNMP状态管理命令: LNMP状态管理: /root/lnmp {start|stop|reload|restart|kill|status}Nginx状态管理:/etc/init.d/nginx ...
- log4cplus基本用法
说起日志系统,不得不提大名鼎鼎的Log4j.特别是使用Java的人们,能够说是无人不知无人不晓无人不用. Log4j以其简单的使用方式(引入一个jar包.一行代码就可以调用).灵活(可通过配置文件任意 ...
- URL 重写
转载自:http://www.cnblogs.com/knowledgesea/archive/2012/10/08/2715350.html 一. 为了页面更有利于seo优化,url重写程序需要做出 ...