python高级编程之装饰器04
from __future__ import with_statement
# -*- coding: utf-8 -*-
# python:2.x
__author__ = 'Administrator'
#with和contextlib
#对于要确保即使发生一个错误时也能运行一些清理代码而言,try...finally语句很有用,对以下场景,如:
"""
关闭一个文件,
释放一个锁
创建一个临时代码补丁
在特殊环境中运行受保护代码
-----------
with语句覆盖了这些场景,为在一个代码块前后调用 一些代码提供了一种简单方法,如:
f=file('files.txt','r')
try:
for line in f:
if line .startswith('#'):
continue
print line
finally:
f.close()
from __future__ import with_statement#在2.5之前需要
with f('f.py') as s:
for i in s:
if i.startswith('#'):
continue
print i
它的相关描述在www.python.org /dev/peps/pep-0343中可以找到
与这个语句兼容的其他来自thread和threadubg模块类
thread as s
threading as s1
s.LockType
s1.Lock
s1.RLock
s1.Condition
s1.Semaphore
s1.BoundedSemaphore
"""
#这些类实现2个:__enter__和__exit__,都来自于with协议,例如:
class Context(object):
def __enter__(self):
print '__eenter__'
def __exit__(self, exc_type, exc_val, exc_tb):
print '__exit__(*)'
if exc_type is None:
print 'with no error'
else:
print 'with an error(%s)'%(exc_val)
with Context():
print '__enter__'
with Context():
print '__exit__(*)'
raise TypeError('i am the bug')
"""
__exit__将获取代码块中发生错误时填入3个参数,如果未出现错误,那么这3个参数都被设置这None,当发生一个错误时,__exit__不应该重新抛出这个错误,因为这是调用者责任
,但是它可以通过返回True来避免这个异常,这个用来实现一些特殊使用场景,但对于大部场景使得而言,这个方法正确行为执行与finally类似清理工作,
不管代码块中发生什么,都不返回任何东西
"""
#contextlib模块
#为了给with语句的提供一些辅助类,标准库添加 了一个模块,名为contextmanager这个一个装饰器,增加包含以yield语句分开的__nter__和__exit__两部分生成器
from contextlib import contextmanager
@contextmanager
def conter():
print u'conter()之装饰器'
try:
yield
except Exception,s:
print 'with an error%s'%s
#在此需要重新抛出错误
raise s
else:
print ' with no error'
"""
如果发生任何异常,该函数需要重新抛出这个异常,以便传递它,注意:contxt在需要时可以有一些参数,只要它们在调用中提供这些参数即可,这个小的
辅助类简化了常规基于类的上下文API,正如生成器使用基于类的迭代器API所做一样
这个模块提供了另外辅助类
closing(element)是由contextmanager装饰函数,它将输入一个元素,然后在退出时调用该元素close方法
nested(c1,c2,...)这是一个合并上下文并使用它们创建嵌套with调用函数.
"""
#上下文实例
import logging
@contextmanager
def logged(k1,l):
#记录器
def _log(f):
def __log(*a,**k):
l(f,a,k)
return f(*a,**k)
return __log
#装饰该类
for attribute in dir(k1):
if attribute.startswith('_'):
continue
elem=getattr(k1,attribute)
setattr(k1,'__logged_%s'%(attribute,elem))
setattr(k1,attribute,_log(elem))
#正常工作
yield k1
#移除日志
for attribute in dir(k1):
if not attribute.startswith('__logged_'):
continue
elem=getattr(k1,attribute)
setattr(k1,attribute[len('__logged_'):],elem)
delattr(k1,attribute)
"""
记录器函数之后可以被用于记录指定上下文中调用API,下一个例子中,调用被添加到一个列表中以跟踪API使用,然后用于执行一些断言
"""
class One(object):
def _private(self):
pass
def one(self,a):
self.two()
a.thing(self)
self._private()
def two(self):
pass
class Two(object):
def thing(self,b):
b.two()
cal=[]
def called(m,a,k):
cal.append(m.in_func.func_name)
with logged(One,cal):
one=One()
two=Two()
one.one(two)
print cal
python高级编程之装饰器04的更多相关文章
- Python模块化编程与装饰器
Python的模块化编程 我们首先以一个例子来介绍模块化编程的应用场景,有这样一个名为requirements.py的python3文件,其中两个函数的作用是分别以不同的顺序来打印一个字符串: # r ...
- python函数式编程之装饰器(一)
1.开放封闭原则 简单来说,就是对扩展开放,对修改封闭 在面向对象的编程方式中,经常会定义各种函数. 一个函数的使用分为定义阶段和使用阶段,一个函数定义完成以后,可能会在很多位置被调用 这意味着如果函 ...
- Python高级--闭包与装饰器
前言:在Python中,闭包是一种非常有用的功能!它通常与装饰器一起搭配使用,可以在不改变被装饰函数的功能的基础上,完成更多的功能.如权限认证. 一.如何定义闭包 1.闭包就是两个嵌套的函数,外层函数 ...
- python函数式编程之装饰器(二)
以前用装饰器,都是定义好了装饰器后,使用@装饰器名的方法写入被装饰函数的正上方 在这里,定义的装饰器都是没有参数的 在定义装饰器的函数的时候,没有在括号里定义参数,这就叫做无参装饰器 既然有无参装饰器 ...
- Python函数式编程之装饰器
原则:对修改是封闭的,对扩展是开放的,方法:一般不修改函数或者类,而是扩展函数或者类 一:装饰器 允许我们将一个提供核心功能的对象和其他可以改变这个功能的对象’包裹‘在一起, 使用装饰对象的任何对象与 ...
- Python编程举例-装饰器
装饰器的通常用途是扩展已定义好的函数的功能 一个浅显的装饰器编程例子 #装饰器函数 def outer(fun): def wrapper(): #添加新的功能 print('验证') fun() r ...
- python高级编程:有用的设计模式2
# -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...
- python高级编程:有用的设计模式1
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...
- python高级编程技巧
由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr ...
随机推荐
- swift 弹窗
直接拷贝使用即可 let alert = UIAlertController(title:nil,message:"输入不能为空",preferredStyle: .Alert) ...
- mybatis 调用mysql存储过程 带输出输入参数
http://lohasle.iteye.com/blog/1669879 存储过程都是一样的,只是根据自己的喜好,可以用MAP或者JAVABEAN传递参数. -- ----------------- ...
- Js获取元素样式值(getComputedStyle¤tStyle)兼容性解决方案
因为:style(document.getElementById(id).style.XXX)只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. 一般js获取内部样式和外部样式使用 ...
- [RxJS] Updating Data with Scan
You often need to update the data flowing through the stream with custom logic based on what you nee ...
- cookie 和 session
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...
- 未能加载文件或程序集“System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”
最近用vs2012发布程序,然后将更新后的程序文件部署到服务器上,由于服务器上本来有此系统,所以只更新了修改的文件 . 进行系统登录时提示:未能加载文件或程序集“System.Web.Extensio ...
- VS2015 新Web项目(C#6)出现CS1617异常的解决
VS2015 新Web项目(C#6)出现CS1617错误的解决 VS2015新增了对C#6的支持. 在新的Web项目模板中通过引入nuget包Microsoft.CodeDom.Providers.D ...
- myeclipse修改内存
安装完成后,在安装目录有个config.ini文件,内容如下:-vmargs-Xms40m-Xmx256m Xms:初始化内存大小xmx:最大内存大小用编辑工具打开他,把Xms 和Xmx更改成自己需要 ...
- 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题
这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...
- -webkit-appearance: none;
今天在web群里聊天的时候,发现了这个东东,我好像不怎么认识他,于是查了下关于他的信息: 抄的例子, ----------- IOS环境下的按钮都是经过美化的,但通常我们在设计web app的时候不需 ...