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 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
随机推荐
- Ubuntu15.10下如何使用EasyGui模块开发Python GUI
偶然的一个机会,发现了github上的这个开源的项目,easygui for python(一个基于TKinter的模块) 感觉很是惊讶,原来python也可以这么简单的开发出一些GUI界面(究其原因 ...
- 深入分析Spring混合事务
在ORM框架的事务管理器的事务内,使用JdbcTemplate执行SQL是不会纳入事务管理的. 下面进行源码分析,看为什么必须要在DataSourceTransactionManager的事务内使用J ...
- android 网络通信框架volly
1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient( ...
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
boost的mutex,condition_variable非常好用.但是在Linux上,boost实际上做的是对pthread_mutex_t和pthread_cond_t的一系列的封装.因此通过对 ...
- Java Web 高性能开发,第 3 部分: 网站优化实战
这个系列的前两篇,介绍了前端的优化技术,这些技术秉承了前人至高无上的智慧,我只是负责吸收和传播.然而,这些技术一般也都是某某大型网站的技术经验,我们大部分人或许只能接触到相对小规模的网站,小规模的网站 ...
- Android指南针之加速度传感器地磁传感器-android学习之旅(67)
由于andorid不推荐用传统的方向传感器,推荐用加速度传感器和地磁传感器来构造得到方向传感器的数据,其实主要是z轴的旋转角度 具体代码示例 代码如下 public class MainActivit ...
- Zookeeper实现数据的发布和订阅
使用场景 当一个对象的改变,需要通知其他对象而且不知道要通知多少个对象,可以使用发布订阅模式 .在分布式中的应用有配置管理(Configuration Management) .集群管理 ...
- 高通msm8994启动流程简介
处理器信息 8994包含如下子系统: 子系统 处理器 含义 APSS 4*Cortex-A53 应用子系统 APSS 4*Cortex-A57 应用子系统 LPASS QDSP6 v5.5A(Hexa ...
- WebService详解(二)
WsExplorer和Tcp/Ip Monitor工具本身就存在于eclipse和MyEclipse中 使用工具的原因: 1. 使用工具可以更好的了解WebService请求的过程 2. 使 ...
- 【一天一道LeetCode】#24. Swap Nodes in Pairs
一天一道LeetCode系列 (一)题目 Given a linked list, swap every two adjacent nodes and return its head. For exa ...