python with语句学习笔记

实现了上下文协议的对象使用with语句

上下文管理器

1. __enter__ __exit__ 的简单使用
class ContextTest(object):

    def __init__(self):
        self.my_dict = dict()

    def __enter__(self):
        self.my_dict["name"] = "Stone"

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.my_dict.pop("name")


my_context = ContextTest()

with my_context:
    print "In with context name: %s " % my_context.my_dict.get("name")

print "Out with context name: %s " % my_context.my_dict.get("name")

执行输入结果

In with context name: Stone 
Out with context name: None 
2. __enter__ 返回值即为with后面as的值(当然也可以为一个对象)
例1
class ContextTest(object):

    def __init__(self):
        self.my_dict = dict()

    def __enter__(self):
        print "Add name to my_dict"
        self.my_dict["name"] = "Stone"
        return self.my_dict["name"]

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.my_dict.pop("name")
        print "Remove name of my_dict"


my_context = ContextTest()

with my_context as ret:
    print "In with context name: %s , ret is: %s" % (my_context.my_dict.get("name"), ret)

print "Out with context name: %s " % my_context.my_dict.get("name")

运行输入结果:

Add name to my_dict
In with context name: Stone , ret is: Stone
Remove name of my_dict
Out with context name: None 
例2
class ContextTest(object):

    def __init__(self):
        self.my_dict = dict()

    def __enter__(self):
        print "Add name to my_dict"
        self.my_dict["name"] = "Stone"
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.my_dict.pop("name")
        print "Remove name of my_dict"

    def query(self, query_key):
        return self.my_dict.get(query_key)


my_context = ContextTest()

with my_context as q:
    print "query name: %s " % q.query("name")

运行输入结果:

Add name to my_dict
query name: Stone 
Remove name of my_dict
3. __exit__ 返回值True/False(False: 发生异常时,会将异常抛出,True: 发生异常时,不会将异常抛出)
返回 False: 发生异常时,会将异常抛出
class ContextTest(object):

    def __init__(self):
        self.my_dict = dict()

    def __enter__(self):
        print "Add name to my_dict"
        self.my_dict["name"] = "Stone"
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.my_dict.pop("name")
        print "Remove name of my_dict"
        print "exc_type is: %s, exc_val is: %s, exc_tb is: %s" % (exc_type, exc_val, exc_tb)
        return False      # return False如果发生异常时,会将异常抛出,return True如果发生异常时,不会将异常抛出

    def query(self, query_key):
        return self.my_dict.get(query_key)


try:
    with ContextTest() as q:
        1/0
        print "query name: %s " % q.query("name")
except Exception as e:
    print "Catch an Exception: %s" % e.message

运行输入结果:

Connected to pydev debugger (build 191.7479.30)
Add name to my_dict
Remove name of my_dict
exc_type is: <type 'exceptions.ZeroDivisionError'>, exc_val is: integer division or modulo by zero, exc_tb is: <traceback object at 0x1015553f8>
Catch an Exception: integer division or modulo by zero
返回True: 发生异常时,不会将异常抛出
class ContextTest(object):

    def __init__(self):
        self.my_dict = dict()

    def __enter__(self):
        print "Add name to my_dict"
        self.my_dict["name"] = "Stone"
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.my_dict.pop("name")
        print "Remove name of my_dict"
        print "exc_type is: %s, exc_val is: %s, exc_tb is: %s" % (exc_type, exc_val, exc_tb)
        return True      # return False如果发生异常时,会将异常抛出,return True如果发生异常时,不会将异常抛出

    def query(self, query_key):
        return self.my_dict.get(query_key)


try:
    with ContextTest() as q:
        1/0
        print "query name: %s " % q.query("name")
except Exception as e:
    print "Catch an Exception: %s" % e.message

运行输入结果:

Add name to my_dict
Remove name of my_dict
exc_type is: <type 'exceptions.ZeroDivisionError'>, exc_val is: integer division or modulo by zero, exc_tb is: <traceback object at 0x1038f7368>
使用contextmanager 实现上下文
yield 上面的代码类似__enter__, yield 后面 类似于 __enter__ return 的值( 可作为as 后面的变量),yield 下面的代码类型 __exit__
from contextlib import contextmanager

class MyResource(object):

    def query(self):
        print("query data")

@contextmanager
def context_my_resource():
    print("connect to resource")  # 类似__enter__
    yield MyResource()   # 类似于 __enter__ return 的值
    print("close resource connection")  # 类似于 __exit__

with context_my_resource() as r:
    r.query()

运行结果:

connect to resource
query data
close resource connection
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值