猜想contextlib模块的contextmanager源码

Python 还提供了⼀个 contextmanager 的装饰器,更进⼀步简化了上下⽂管理器的实现⽅式。通过
yield 将函数分割成两部分,yield 之前的语句在 __enter__ ⽅法中执⾏,yield 之后的语句在 __exit__⽅法中执⾏。紧跟在 yield 后⾯的值是函数的返回值。

from contextlib import contextmanager
@contextmanager
def func(path, mode):
        f = open(path, mode)
        yield f
        f.close()

1、简单猜想contextmanager源码:

class manager:
    def __init__(self, path, mode):
        self.func = func(path, mode)
        self.path = path
        self.mode = mode

    def __enter__(self):
        return next(self.func)

    def __exit__(self, *args):
        try:
            next(self.func)
        except StopIteration:
            print("catch stopIter!")


def func(file, mode):
    print("opening")
    f = open(file, mode)
    yield f
    print("closing")
    f.close()


if __name__ == '__main__':
    with manager("./out.txt", "w") as f:
        f.write("2013.5.13")

2、进阶猜想contextmanager源码:

class manager:
    def __init__(self, func):
        self.func = func
        self.args = None
        self.kwargs = None
        self.generator = None

    def __enter__(self):
        self.generator = self.func(*self.args, **self.kwargs)
        return next(self.generator)

    def __exit__(self, *args):
        try:
            next(self.generator)
        except StopIteration:
            print("catch stopIter!")

    def __call__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        return self

@manager
def func(file, mode):
    print("opening")
    f = open(file, mode)
    yield f
    print("closing")
    f.close()


if __name__ == '__main__':
    with func("./out.txt", "w") as f:
        f.write("2023.5.13") 

在下新手,代码逻辑有点乱,还有优化空间。大概能实现contextmanager装饰器类似功能。


                
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值