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的更多相关文章

  1. Python模块化编程与装饰器

    Python的模块化编程 我们首先以一个例子来介绍模块化编程的应用场景,有这样一个名为requirements.py的python3文件,其中两个函数的作用是分别以不同的顺序来打印一个字符串: # r ...

  2. python函数式编程之装饰器(一)

    1.开放封闭原则 简单来说,就是对扩展开放,对修改封闭 在面向对象的编程方式中,经常会定义各种函数. 一个函数的使用分为定义阶段和使用阶段,一个函数定义完成以后,可能会在很多位置被调用 这意味着如果函 ...

  3. Python高级--闭包与装饰器

    前言:在Python中,闭包是一种非常有用的功能!它通常与装饰器一起搭配使用,可以在不改变被装饰函数的功能的基础上,完成更多的功能.如权限认证. 一.如何定义闭包 1.闭包就是两个嵌套的函数,外层函数 ...

  4. python函数式编程之装饰器(二)

    以前用装饰器,都是定义好了装饰器后,使用@装饰器名的方法写入被装饰函数的正上方 在这里,定义的装饰器都是没有参数的 在定义装饰器的函数的时候,没有在括号里定义参数,这就叫做无参装饰器 既然有无参装饰器 ...

  5. Python函数式编程之装饰器

    原则:对修改是封闭的,对扩展是开放的,方法:一般不修改函数或者类,而是扩展函数或者类 一:装饰器 允许我们将一个提供核心功能的对象和其他可以改变这个功能的对象’包裹‘在一起, 使用装饰对象的任何对象与 ...

  6. Python编程举例-装饰器

    装饰器的通常用途是扩展已定义好的函数的功能 一个浅显的装饰器编程例子 #装饰器函数 def outer(fun): def wrapper(): #添加新的功能 print('验证') fun() r ...

  7. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  8. python高级编程:有用的设计模式1

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...

  9. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

随机推荐

  1. cocos2d-x核心基础类

    Application 应用程序入口类 EGLView 绘图句柄 Director Node Layer Scene

  2. Collections.sort()

    Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f, ...

  3. C++内存泄露检測原理

    转自:http://hi.baidu.com/jasonlyy/item/9ca0cecf2c8f113a99b4981c 本文针对 linux 下的 C++ 程序的内存泄漏的检測方法及事实上现进行探 ...

  4. [Cycle.js] Making our toy DOM Driver more flexible

    Our previous toy DOM Driver is still primitive. We are only able to sends strings as the textContent ...

  5. _js day10

  6. C#遍历Object各个属性含List泛型嵌套。

    同事遇到一个问题:在做手机app接口时,返回JSON格式,json里面的数据属性均是string类型,但不能出现NULL(手机端那边说处理很麻烦,哎).Model已经创建好了,而且model的每个属性 ...

  7. android内存优化之图片压缩和缓存

    由于手机内存的限制和网络流量的费用现在,我们在加载图片的时候,必须要做好图片的压缩和缓存. 图片缓存机制一般有2种,软引用和内存缓存技术. 1.压缩图片:压缩图片要既不能模糊,也不能拉伸图片. 图片操 ...

  8. ORACLE触发器概述之【语句触发器】【weber出品】

    一.触发器概述 与表,视图,模式,或者数据库相关的PL/SQL过程,当触发条件被触发时,自动执行 分类: 1.语句触发器 2.行触发器 二.语句触发器 1. 什么是语句触发器 语句触发器,是指当执行D ...

  9. call()与apply()传参需要注意的一点

    call()与apply()是用来改变函数体内的this指向,第一个参数是调用函数的母对象,他是调用上下文,函数体内通过this来获得对它的引用,换句话说就是第一参数===函数中的this. 但是如下 ...

  10. C++中explicit

    [explicit] 1.用于抑制隐式转换,即: X x = ; // error X x(); // ok 2.只对一个实参的构造函数有效,但是,可以用多有多个实参的构造函数,目前没有意义: cla ...