Effective Python 读书笔记: 第43条: 考虑以contextlib和with语句来改写可复用的try/finally代码

# -*- encoding: utf-8 -*-

from contextlib import contextmanager
import logging

'''
第43条: 考虑以contextlib和with语句来改写可复用的try/finally代码

关键:
1 with语句
作用: 进行文件关闭,资源清理,锁的获取与释放等
支持with: 
方式1:用contextlib模块处理自己编写的对象和函数
    提供了contextmanager的装饰器
方式2: 定义一个类,提供__enter__和__exit__的特殊方法

2 使用带有目标的with语句
用法: 传给with语句的那个情境管理器,本身可以返回一个对象
with中的as: 指定一个局部变量,会把情境管理器的对象,赋给这个局部变量
应用场景:
打开文件,as指定变量接收open返回的文件句柄

3 情境管理器
用法:在情境管理器中通过yield语句返回值,然后另自己的函数把该值提供给
as指定的目标变量
用法示例:
@contextmanager
def logLevel(level, name):
    logger = logging.getLogger(name)
    oldLevel = logger.getEffectiveLevel()
    logger.setLevel(level)
    try:
        yield logger
    finally:
        logger.setLevel(oldLevel)

with logLevel(logging.DEBUG, 'myLog') as logger:
    logger.debug('I like python.')


4 总结
contextlib.contextmanager装饰器可以修饰函数,来让函数支持with语句,
只需要在该函数中原来return返回的地方修改为yield, 则as关键字就可以将
返回的结果赋值给一个局部变量。


参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''
def func():
    logging.debug('debug data')
    logging.error('error data')
    logging.debug('debug data')


@contextmanager
def debugLogging(level):
    logger = logging.getLogger()
    oldLevel = logger.getEffectiveLevel()
    logger.setLevel(level)
    try:
        yield
    finally:
        logger.setLevel(oldLevel)


def useContextManager():
    with debugLogging(logging.DEBUG):
        print "Inside"
        func()
    print "After"
    func()

    with logLevel(logging.DEBUG, 'myLog') as logger:
        logger.debug('I like python.')
        logging.debug('This will not print.')
    logger = logging.getLogger('myLog')
    logger.debug('Debug will do not print.')
    logger.error('Error will print.')

def useWith():
    with open('/tmp/data.txt', 'w') as handle:
        handle.write("I like python.")


@contextmanager
def logLevel(level, name):
    logger = logging.getLogger(name)
    oldLevel = logger.getEffectiveLevel()
    logger.setLevel(level)
    try:
        yield logger
    finally:
        logger.setLevel(oldLevel)


def process():
    useContextManager()
    useWith()


if __name__ == "__main__":
    process() 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值