python函数与装饰器
一、名字空间与作用域
1.名字空间
名字空间:赋值语句创建了约束,用来存储约束的dict被称为名字空间
赋值语句的行为:1.分别在堆和栈中创建obj与name
2.将obj与name进行绑定
注:具有赋值行为的语句均可以称为赋值语句,如class A(),def a(),import a等
名字空间的划分:local、global、builtin(用来存储module层次的约束)
2.名字空间的可见性
a = 1
def func():
print a #UnbundlocalError
a = 2
print a #
作用域:约束的作用域仅仅由源程序的文本决定,而不是在运行时动态决定的。因此,python具有静态作用域。
作用域与名字空间的关系:作用域在静态时已决定了名字空间中的name,但name所对应的obj在动态时决定。
注:1、变量能否访问由是否处于同一作用域决定(编译时处理),访问所得值在运行时确定。
2、由一个赋值语句引用的名字在这个赋值语句所在的作用域里是可见的,与代码顺序无关。
3.嵌套规则
LGB:由赋值语句引进的名字在这个赋值语句的内部嵌套的作用域内都是可见的,除非内部作用域中有相同的名字将其屏蔽。
LEGB:
a = 1
def func():
a = 2
def l():
print a
return l
f = func()
f() #输出结果为2
闭包:a = 2,def l均处于func内的同一作用域中,执行f = func()时会将其进行捆绑,并将捆绑后的结果返回。这个捆绑起来的整体即为闭包。
二、函数
1.函数对象的实现 ———— PyFuncionObject
PyFuncionObject:python运行时动态产生,即执行def语句时创建。在PyFunctionObject中储存着函数运行时所需的动态信息。
注:每调用一次函数就会创建一个PyFunc,因为函数调用时具有不同的上下文环境。
2.函数实现上的分离
def func():
a = 1
def f():
print a
return f
func()()
对于def f(),在虚拟机中其声明与实现是分离的。声明是在func函数名字空间中的一条约束,而函数体则是一个绑定了上下文信息的PyFunc
函数的参数传递机制:根据参数对象为可变对象还是不可变对象来表现为值传递还是地址传递。
参数种类:参数种类多达5种。分别为必选参数、默认参数、可变参数、命名关键字参数和关键字参数,在参数列表中的位置也需要如此。对于任意函数,都可以通过类似func(*args, **kw)的形式调用它。
三、装饰器
1、原理:
最内嵌套作用域规则(LGB)
2、实现:
最简单的装饰器
def f(func):
def g():
print 'g..'
func()
return g @f
def a():
print 'a'
带参数的装饰器
#-*- encoding: utf8 -*- from functools import wraps
import logging def logged(level,name=None,message=None): def decorate(func):
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = message if message else func.__name__ @wraps(func)
def wrapper(*args,**kwargs):
print args
print kwargs
log.log(level,logmsg)
return func(*args,**kwargs)
return wrapper
return decorate @logged(logging.DEBUG)
def add(x,y):
return x + y @logged(logging.CRITICAL,'example')
def spam():
print 'spam' add(3,4) ==> logged(logging.DEBUG)(add)(3,4)
#将函数对象作为参数传进修饰器函数中
#被装饰的函数只是作为参数 在装饰器函数中只返回函数对象使用add()(3,4) 调用也可以
#函数wrapper以外的内容只会在定义被装饰的函数时执行一次,仅wrapper函数内的内容才会随着被装饰的函数的调用而执行。即定义被装饰函数时就已执行logged(logging.DEBUG)(add),以后的每次调用只会执行(3,4)部分 '''
注:1.装饰器函数logged接收装饰器参数,提供闭包时的变量环境装饰器内的函数decorate接收被装饰的函数的对象wrapper函数通过*args,**kwargs接收被装饰函数的参数
2.一层函数一个return,最终返回最底层函数的对象
3.构建了一个两层的闭包环境。内层闭包环境可以访问外层闭包环境,外层闭包环境不可以访问内层
4.通过使用wraps装饰器,可以保证func的元数据不变
'''
注:1、闭包用于绑定运行时环境。
2、装饰器用于对函数重新进行封装,在函数执行前后添加操作。
python函数与装饰器的更多相关文章
- Python函数06/装饰器
Python函数06/装饰器 目录 Python函数06/装饰器 内容大纲 1.装饰器 1.1 开放封闭原则 1.2 装饰器 2.今日练习 内容大纲 1.装饰器 1.装饰器 1.1 开放封闭原则 扩展 ...
- python——函数之装饰器
1 问题 实际生活中,我们很难一次性就把一个函数代码写得完美无缺.当我们需要对以前的函数添加新功能时,我们应该怎么做? 2 问题解决思路 (1)可以直接修改原来的函数,在函数内直接修改.当我们对多个函 ...
- python函数、装饰器、迭代器、生成器
目录: 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象: 函数是第一类对象,即函数可以当作数据传递 ...
- Python 函数之装饰器
1.函数 #### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print ...
- python函数闭包-装饰器-03
可调用对象 callable() # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即 callable(对象) 返回为 True 的对象 x = 1 print(cal ...
- Python函数的装饰器修复技术(@wraps)
@wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法: from ...
- Python函数的装饰器修复技术(@wraps)
@wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法 from ...
- Python函数加工厂-装饰器
引言: 函数和装饰器好比程序界的加工厂: 1.函数一般可用来加工一种或者多种数据类型的数据:字符串.数字.列表.字典等 举一个简单例子:已知半径求面积 def s(r): s = 3.14 * r * ...
- Python函数的装饰器
函数的装饰器. 1. 装饰器 开闭原则: 对功能的扩展开放 对代码的修改是封闭 通用装饰器语法: def wrapper(fn): def inner(*args, **kwargs): # 聚合 & ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
随机推荐
- 03 CheckBox 复选框
五 CheckBox 复选框 >概念:可以从一个集合选项中选择一个或者多个选项 >属性:checked 选择状态 >使用: > ...
- (八十六)使用系统自带的分享框架Social.framework
使用Social.framework十分简单,能够便捷的分享到主流的社交框架. ①导入主头文件 #import <Social/Social.h> ②以新浪微博为例,首先判断服务是否可用, ...
- 如何在Cocos2D 1.0 中掩饰一个精灵(四)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了完成需要的效果,我们将使用如下策略: 我们将首先绘制掩饰精灵 ...
- Web Service进阶(四)WebService注解
@WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值为 Java 类的简单名称 + Service.(字符 ...
- 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建一个简单的动态Cubemap系统
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- Oracle生成查询包含指定字段名对应的所有数据表记录语句
应用场合:已知字段名字,查询数据库中所有数据表中包含该字段名的所有数据表 操作办法:指定字段名,数据库表用户,执行下面查询语句即可 --Oracle生成查询包含指定字段名对应的所有数据表记录语句 de ...
- OJ题:输入一个多位的数字,求各数位相加。
题目内容: 输入一个多位的数字,1求各数位相加. 例如输入12345,则计算1+2+3+4+5=15 输入格式: 一个整数 输出格式: 一个整数 输入样例: 1234567890 输出样例: 45 时 ...
- 数据结构基础(21) --DFS与BFS
DFS 从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈). //使用邻接矩阵存储的无向图的深度 ...
- uploadify在火狐下上传不了的解决方案,java版(Spring+SpringMVC+MyBatis)详细解决方案
由于技术选型的原因,在一个产品中,我选择了uploadify,选择它的原因是它有完善的技术文档说明(http://www.uploadify.com/documentation/),唯一不足的是 ...
- 11_Eclipse中演示Git版本的创建,历史版本的修改,创建分支,合并历史版本和当前版本
1 执行以下案例: 某研发团队2011年初开发了一款名为Apollo的信息系统,目前已发布v1.0版本.此项目初期已有部分基础代码, 研发团队再此基础代码上经过3个月的努力发布了一个功能相对完备 ...