码迷,mamicode.com
首页 > 编程语言 > 详细

python高级编程之装饰器04

时间:2014-08-20 22:26:32      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:使用   os   io   文件   for   ar   art   代码   

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,布布扣,bubuko.com

python高级编程之装饰器04

标签:使用   os   io   文件   for   ar   art   代码   

原文地址:http://www.cnblogs.com/mhxy13867806343/p/3925616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!