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

2018 年 10 月 29 日
 northisland
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

请教这要怎么搞?

2655 次点击
所在节点    问与答
8 条回复
northisland
2018 年 10 月 29 日
```
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 理解不深入。
laobubu
2018 年 10 月 29 日
__enter__ 应该是不能控制 with 后面的块的吧。我能想到的就是 raise 个异常,让后面的代码全部都不能跑。
说回来,我觉得优雅点的做法可以 with Tag("xxx") as tag: 然后下一行就是 if tag.will_run:
misaka19000
2018 年 10 月 29 日
感觉应该做不到
lolizeppelin
2018 年 10 月 29 日
enter 里直接 raise
lolizeppelin
2018 年 10 月 29 日
有需要再套一层不就得了
Trim21
2018 年 10 月 29 日
考虑用装饰器?
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()
lance6716
2018 年 10 月 29 日
运行过程不会影响其他过程,除非抛异常
Wincer
2018 年 10 月 29 日
```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
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/502259

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX