【发布时间】:2016-02-29 14:28:01
【问题描述】:
我有一个控制台脚本,它使用ftplib 作为后端从 ftp 服务器获取大量文件。我想使用tqdm 给用户一些反馈,前提是他们打开了“详细”开关。这必须是可选的,因为某些用户可能会在没有tty 访问权限的情况下使用脚本。
ftplib 的retrbinary 方法需要一个回调,因此应该可以将tqdm 以某种方式挂在那里。但是,我不知道这个回调会是什么样子。
【问题讨论】:
我有一个控制台脚本,它使用ftplib 作为后端从 ftp 服务器获取大量文件。我想使用tqdm 给用户一些反馈,前提是他们打开了“详细”开关。这必须是可选的,因为某些用户可能会在没有tty 访问权限的情况下使用脚本。
ftplib 的retrbinary 方法需要一个回调,因此应该可以将tqdm 以某种方式挂在那里。但是,我不知道这个回调会是什么样子。
【问题讨论】:
来自FTP.retrbinary:
每个接收到的数据块都会调用回调函数,单个字符串参数给出数据块。
所以回调可能是这样的:
with open(filename, 'wb') as fd:
total = ftpclient.size(filename)
with tqdm(total=total) as pbar:
def callback_(data):
l = len(data)
pbar.update(l)
fd.write(data)
ftpclient.retrbinary('RETR {}'.format(filename), callback_)
注意:此代码未经测试,可能需要修改。
【讨论】:
if (raw_file.tell() == filesize): tqdm_instance.close()
该代码不应该工作,因为当with 块终止时pbar 将被“关闭”,这发生在ftpclient.retrbinary(...) 之前。你需要一个非常小的缩进模式:
with open(filename, 'wb') as fd:
total = ftpclient.size(filename)
with tqdm(total=total,
unit='B', unit_scale=True, unit_divisor=1024,
disable=not verbose) as pbar:
def cb(data):
pbar.update(len(data))
fd.write(data)
ftpclient.retrbinary('RETR {}'.format(filename), cb)
EDIT 添加了disable 标志和字节缩放
【讨论】:
with open(filename, 'wb') as fd:
total = ftpclient.size(filename)
with tqdm(total=total,
unit='B', unit_scale=True, unit_divisor=1024,
disable=not verbose) as pbar:
def cb(data):
pbar.update(len(data))
fd.write(data)
ftpclient.retrbinary('RETR {}'.format(filename), cb)
【讨论】: