问题描述
我的主要目标是通过 subprocess
在另一个 python 脚本(调用者脚本)中运行外部 python 脚本(客户端脚本)。调用者脚本的控制台显示来自客户端脚本的所有输出 tqdm 输出除外 - 因此它不是通过 subprocess
显示输出的一般问题,而是与 {{ 1}} 与 subprocess
互动。
我的次要目标是我想了解它:)。非常感谢深思熟虑的解释。
客户端脚本 (train.py) 包含多个 tqdm 调用。到目前为止,我还没有看到各种 tqdm 参数配置之间的输出差异太大,所以让我们使用最简单的。
在tqdm
中:
train.py
调用者脚本 ...
from tqdm import tqdm
with tqdm(total = 10,ncols = 80,file=sys.stdout,position = 0,leave = True,desc='f5b: pbar.set_postfix') as pbar:
for i in range(10):
pbar.update(1)
postfix = {'loss': '{0:.4f}'.format(1+i)}
pbar.set_postfix(**postfix)
sleep(0.1)
执行函数 experiment.py
,该函数通过参数 execute_experiment
调用 train.py
:
command_list
此脚本调用上面的 train.py 代码片段确实返回输出,但 tqdm 输出在 0 秒后停止,如下所示:
def execute_experiment(command_list):
tic = time.time()
try:
process = subprocess.Popen(
command_list,shell=False,encoding='utf-8',bufsize=0,stdin=subprocess.DEVNULL,universal_newlines=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE
)
# Poll process for new output until finished
# Source: https://stackoverflow.com/q/37401654/7769076
while process.poll() is None:
nextline = process.stdout.readline()
sys.stdout.write(nextline)
sys.stdout.flush()
except CalledProcessError as err:
print("CalledProcessError: {0}".format(err))
sys.exit(1)
except OSError as err:
print("OS error: {0}".format(err))
sys.exit(1)
except:
print("Unexpected error:",sys.exc_info()[0])
raise
if (process.returncode == 0):
toc = time.time()
time1 = str(round(toc - tic))
return time1
else:
return 1
对train.py原始代码的脚本调用返回所有输出除了 tqdm输出:
f5b: pbar.set_postfix: 0%| | 0/10 [00:00<?,?it/s]
f5b: pbar.set_postfix: 10%|█▊ | 1/10 [00:00<00:00,22310.13it/s]
评论:
-
Training default configuration train.py data --use-cuda ... device: cuda ...
:作为python脚本调用python脚本。当shell = False
时,根本不调用客户端脚本 -
shell=True
:防止缓冲 -
bufsize=0
调用以train.py
开头,以确保在本地机器上调用相应 conda 环境的 python 解释器。
问题:
-
sys.executable
是否会阻止向上游传递进度条输出?我知道当调用tqdm.set_postfix
时会发生这种情况,例如作者:pbar.set_description('已处理:%d' %(1 + i))
此代码包含它:
tqdm.set_description
调用顺序为 def train(self,DataLoader,max_batches=500,verbose=True,**kwargs):
with tqdm(total=max_batches,disable=not verbose,**kwargs) as pbar:
for results in self.train_iter(DataLoader,max_batches=max_batches):
pbar.update(1)
postfix = {'loss': '{0:.4f}'.format(results['mean_outer_loss'])}
if 'accuracies_after' in results:
postfix['accuracy'] = '{0:.4f}'.format(
np.mean(results['accuracies_after']))
pbar.set_postfix(**postfix)
# for logging
return results
> experiment.py
> train.py
。
nested.py
通过以下方式调用 train.py
中的 train 函数:
对于范围内的纪元(args.num_epochs):
nested.py
尝试替代方案但未成功:
results_Metatraining = Metalearner.train(Meta_train_DataLoader,max_batches=args.num_batches,verbose=args.verbose,desc='Training',# leave=False
leave=True
)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)