为什么功能正常工作而不指定参数? [英] Why function works properly without specifying parameters?
问题描述
在下面的代码中,我不明白为什么 download_progress_hook
在从 maybe_download $ c
。
$ b download_progress_hook
的定义表明有三个参数需要传递:
但是,当从 maybe_download
调用 download_progress_hook
时,没有参数传递。为什么它不会失败?
以下是完整的代码:
url ='http://commondatastorage.googleapis.com/books1000/'
last_percent_reported = None
data_root ='。'#改变我在别处存储数据
def download_progress_hook(count,blockSize,totalSize):
一个钩子报告下载进度,主要用于
网速较慢的用户,下载进度每下降5%。
全局last_percent_reported
百分比= int(count * blockSize * 100 / totalSize)
如果last_percent_reported!=百分比:
如果百分比% 5 == 0:
sys.stdout.write(%s %%%percent)
sys.stdout.flush()
else:
sys.stdout.write (。)
sys.stdout.flush()
last_percent_reported = percent
$ b $ def maybe_download(filename,expected_bytes,force = False):
如果文件不存在,请下载文件,并制作su
dest_filename = os.path.join(data_root,filename)
如果强制或不强制os.path.exists(dest_filename):
print('Attempting下载:',文件名)
文件名,_ = urlretrieve(url +文件名,dest_filename,reporthook = download_progress_hook)
print('\\\
Download 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 +'。 ')
return dest_filename
train_filename = maybe_download('notMNIST_large.tar.gz',247336696)
test_filename = maybe_download('notMNIST_small。 tar.gz',8458043)
那是你出错的地方。该功能未被调用。它只被引用。这里没有 Python函数是一流的对象,你可以通过它们或将它们分配给其他名称: 这里 所以下面的表达式: download_progress_hook
从函数 maybe_download
中调用
(...)
调用表达式。
>>> def foo(bar):
... return bar + 1
...
>>> foo
<函数0x00e20410处的foo>
>>> spam = foo
>>>垃圾邮件
<函数foo在0x100e20410>
>>>垃圾邮件(5)
6
spam
是对函数对象 foo
的另一个引用。
urlretrieve(
url + filename,dest_filename,
reporthook = download_progress_hook)
不会调用 download_progress_hook
。它只是将该函数对象赋给 urlretrieve()
函数,它是代码,它将调用 download_progress_hook
somewhere(传入所需参数)。
从 URLOpener.retrieve
文档(最终处理该钩子):
$ b
如果给出 reporthook ,它必须是一个接受三个数字参数的函数:块数,最大值大小块被读入并且下载的总大小(如果未知,则为-1)。它将在开始时被调用一次,并且在从网络读取每个数据块之后。
In the below code, I don't understand why download_progress_hook
works without passing parameters when it is called from within the maybe_download
method.
The definition of download_progress_hook
states that there are three parameters that have to be passed: count, blockSize, totalSize
.
But, when the download_progress_hook
is called from maybe_download
there are no parameters passed. Why doesn't it fail?
Here is the full code:
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)
I get everything, but the point where the function
download_progress_hook
gets called from within functionmaybe_download
That's where you went wrong. The function is not being called. It is only being referenced. There is no (...)
call expression there.
Python functions are first-class objects, you can pass them around or assign them to other names:
>>> def foo(bar):
... return bar + 1
...
>>> foo
<function foo at 0x100e20410>
>>> spam = foo
>>> spam
<function foo at 0x100e20410>
>>> spam(5)
6
Here spam
is another reference to the function object foo
. I can call that function object through that other name too.
So the following expression:
urlretrieve(
url + filename, dest_filename,
reporthook=download_progress_hook)
doesn't call download_progress_hook
. It merely gives that function object to the urlretrieve()
function, and it is that code that'll call download_progress_hook
somewhere (passing in the required arguments).
From the URLOpener.retrieve
documentation (which ultimately handles that hook):
If reporthook is given, it must be a function accepting three numeric parameters: A chunk number, the maximum size chunks are read in and the total size of the download (-1 if unknown). It will be called once at the start and after each chunk of data is read from the network.
这篇关于为什么功能正常工作而不指定参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!