如何在条件下插入'with'语句?



我有一段代码的结构是这样的:

try:
from tqdm import tqdm
use_tqdm = True
except ImportError:
use_tqdm = False

if use_tqdm:
with tqdm(total=5) as pbar:
# --- many nested for loops ---
pbar.update(1)
else:
# --- identical nested for loops, without pbar.update(1) ---

如何避免重复上述长代码块?

我不能只把条件放在里面的单个pbar行上,因为tqdm所做的是创建一个进度条,所以它只需要实例化一次。

我想我正在寻找一种方法来告诉Python";嘿,只在use_tqdm = True的情况下考虑with语句,否则就假装它不存在",但任何其他建议都是非常受欢迎的。

谢谢!

(tqdm包:https://github.com/tqdm/tqdm(

try:
from tqdm import tqdm
except ImportError:
class tqdm:
def __int__(self, *args, **kwargs):
pass
def __enter__(self):
class Dummy:
def update(self, *args, **kwargs):
pass
return Dummy()
def __exit__(self, *args):
pass
with tqdm(total = 5) as pbar:
--- many nested for loops ---
pbar.update(1)

如果导入失败,您只需要获得一个伪上下文和一个对象,该对象的update方法是no-op。不需要单独的代码。

所以这里有两个单独的问题:

  • 复制但非常相似的代码
  • 有条件的资源分配

对于第一个定义一个函数,该函数可选地采用CCD_;忽略我";。正如@Michael Butscher建议的那样,要么创建一个在所有想要忽略的函数中都只有pass的伪类,要么更脏一点,用if来保护任何出现。示例:

class PbarDummy:
def update(self, _):
pass
def many_for_loops(pbar=PbarDummy()):
--- many nested for loops ---
pbar.update(1)

这也解决了第二个问题,因为您可以有条件地调用with块内的函数。

if use_tqdm:
with tqdm(total = 5) as pbar:
many_for_loops(pbar=pbar)
else:
many_for_loops()

您可以为嵌套了pbar的循环创建一个函数。在该函数中,您检查传入的pbar是否为None,这意味着不更新进度条,否则使用它并调用update:

try:
from tqdm import tqdm
use_tqdm = True
except ImportError:
use_tqdm = False
def process_nested_for_loops(pbar):
# --- many nested for loops ---
if pbar is not None:
pbar.update(1)

if use_tqdm = True:
with tqdm(total = 5) as pbar:
process_nested_for_loops(pbar)
else:
process_nested_for_loops(None)

最新更新