在下面的代码中,当download_progress_hook
方法中调用参数时,我不明白为什么maybe_download
无法传递参数。
download_progress_hook
的定义指出必须传递三个参数:count, blockSize, totalSize
。
但是,当从download_progress_hook
调用maybe_download
时,没有传递参数。为什么它不会失败?
以下是完整代码:
url = 'http://commondatastorage.googleapis.com/books1000/'
last_percent_reported = None
data_root = '.' # Change me to store data elsewhere
def download_progress_hook(count, blockSize, totalSize):
"""A hook to report the progress of a download. This is mostly intended for users with
slow internet connections. Reports every 5% change in download progress.
"""
global last_percent_reported
percent = int(count * blockSize * 100 / totalSize)
if last_percent_reported != percent:
if percent % 5 == 0:
sys.stdout.write("%s%%" % percent)
sys.stdout.flush()
else:
sys.stdout.write(".")
sys.stdout.flush()
last_percent_reported = percent
def maybe_download(filename, expected_bytes, force=False):
"""Download a file if not present, and make sure it's the right size."""
dest_filename = os.path.join(data_root, filename)
if force or not os.path.exists(dest_filename):
print('Attempting to download:', filename)
filename, _ = urlretrieve(url + filename, dest_filename, reporthook=download_progress_hook)
print('\nDownload Complete!')
statinfo = os.stat(dest_filename)
if statinfo.st_size == expected_bytes:
print('Found and verified', dest_filename)
else:
raise Exception(
'Failed to verify ' + dest_filename + '. Can you get to it with a browser?')
return dest_filename
train_filename = maybe_download('notMNIST_large.tar.gz', 247336696)
test_filename = maybe_download('notMNIST_small.tar.gz', 8458043)
答案 0 :(得分:6)
我得到了所有内容,但是从函数
中调用函数download_progress_hook
maybe_download
的点
那是你出错的地方。该函数未被调用。它只被引用。那里没有(...)
调用表达式。
Python函数是第一类对象,您可以传递它们或将它们分配给其他名称:
>>> def foo(bar):
... return bar + 1
...
>>> foo
<function foo at 0x100e20410>
>>> spam = foo
>>> spam
<function foo at 0x100e20410>
>>> spam(5)
6
此处spam
是对函数对象foo
的另一个引用。我也可以通过其他名称调用该函数对象。
所以表达式如下:
urlretrieve(
url + filename, dest_filename,
reporthook=download_progress_hook)
不致电 download_progress_hook
。它只是将该函数对象赋予urlretrieve()
函数,并且代码将在某处调用download_progress_hook
(传递所需的参数)。
来自URLOpener.retrieve
documentation(最终处理该钩子):
如果给出 reporthook ,它必须是一个接受三个数字参数的函数:一个块号,读入的最大大小块和下载的总大小(如果未知,则为-1)。它将在开始时调用一次,并在从网络读取每个数据块之后调用。
答案 1 :(得分:1)
import urllib.request
import os
class Progress:
def __init__(self):
self.old_percent = 0
def download_progress_hook(self, count, blockSize, totalSize):
percent = int(count * blockSize * 100 / totalSize)
if percent > self.old_percent:
self.old_percent = percent
os.system('cls')
print(percent, '%')
if percent == 100:
os.system('cls')
print('done!')
title = 'title'
url_mp4 = 'https://url'
progress = Progress()
urllib.request.urlretrieve(url_mp4, title + '.mp4', reporthook=progress.download_progress_hook)
答案 2 :(得分:0)
我喜欢ICEBURG的答案,但是os.system('cls')不可移植,所以我用ASCII制作了进度条:
=COUNTIFS($A:$A,$E2,$C:$C,RIGHT(F$1,LEN(F$1)-LEN("# of items ")))
它输出:
class ProgressBar:
def __init__(self):
self.old_percent = 0
print('_' * 50)
def download_progress_hook(self, count, blockSize, totalSize):
percent = int(count * blockSize * 100 / totalSize)
if percent >= 2 + self.old_percent:
self.old_percent = percent
# print(percent, '%')
print('>', end='')
sys.stdout.flush()
if percent == 100:
print('\ndone!')