Skip to content Skip to sidebar Skip to footer

Why Function Works Properly Without Specifying Parameters?

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 downloa

Solution 1:

I get everything, but the point where the function download_progress_hook gets called from within function maybe_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:

>>>deffoo(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 calldownload_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.

Solution 2:

import urllib.request
import os

classProgress:
def__init__(self):
    self.old_percent = 0defdownload_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)

Solution 3:

I like ICEBURG's answer, but os.system('cls') isn't portable so I made a progress bar with ASCII:

classProgressBar:
    def__init__(self):
        self.old_percent = 0print('_' * 50)

    defdownload_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!')

It outputs:

__________________________________________________
>>>>>>>>>>>>>>>>>>>>>>>>>

Post a Comment for "Why Function Works Properly Without Specifying Parameters?"