首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
V2EX  ›  问与答

请教各位, Python 能实现这种 with 类么?

  •  
  •   northisland · 266 天前 · 737 次点击
    这是一个创建于 266 天前的主题,其中的信息可能已经有所发展或是发生改变。
    with Tag('这就是一个简单说明', will_run=True):
    	codes...
    

    就是这样will_runFalse 的话, 后面的代码就不执行,或者执行但是无效。

    我想不出怎么用 __init____enter____exit__搞定

    所以来问一下大家。

    我 1 楼的思路,测试下来被打脸了:

    In [1]: class Tag(object):
       ...:     def __init__(self, comment, will_run=True):
       ...:         self.will_run = will_run
       ...:     def __enter__(self):
       ...:         if not self.will_run:
       ...:             return
       ...:     def __exit__(self, *exec_info): pass
       ...:
    
    In [2]: with Tag('这是一个实验', will_run=True):
       ...:     print(123456)
       ...:
    123456
    
    In [3]: with Tag('这是一个实验', will_run=False):
       ...:     print(123456)
       ...:
    123456
    

    请教这要怎么搞?

    8 回复  |  直到 2018-10-29 19:14:16 +08:00
        1
    northisland   266 天前
    ```
    class Tag(object):
    def __init__(self, comment, will_run=True):
    self.will_run = will_run

    def __enter__(self):
    if self.will_run==False:
    return

    def __exit__(self, *exec_info): pass
    ```

    是这样么?我去执行试试~~对 enter 理解不深入。
        2
    laobubu   266 天前
    __enter__ 应该是不能控制 with 后面的块的吧。我能想到的就是 raise 个异常,让后面的代码全部都不能跑。
    说回来,我觉得优雅点的做法可以 with Tag("xxx") as tag: 然后下一行就是 if tag.will_run:
        3
    misaka19000   266 天前
    感觉应该做不到
        4
    lolizeppelin   266 天前 via Android
    enter 里直接 raise
        5
    lolizeppelin   266 天前 via Android
    有需要再套一层不就得了
        6
    Trim21   266 天前   ♥ 1
    考虑用装饰器?
    def tag(name, with_run: bool = False):
    def wrapper(func):
    if with_run:
    func()

    return wrapper


    def main():
    @tag("this is a tag", with_run=False)
    def f1():
    print("f1")

    @tag("this is a tag", with_run=True)
    def f2():
    print("f2")


    if __name__ == '__main__':
    main()
        7
    lance6716   266 天前
    运行过程不会影响其他过程,除非抛异常
        8
    Wincer   266 天前
    ```python
    from contextlib import contextmanager

    @contextmanager
    def test(will_run=True):
    if will_run:
    yield 233
    else:
    return ""

    try:
    with test(will_run=False) as q:
    print(1234)
    except RuntimeError:
    pass
    ```
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3417 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 05:33 · PVG 13:33 · LAX 22:33 · JFK 01:33
    ♥ Do have faith in what you're doing.