Jak vytisknout "tečky" (nebo jiný druh zpětné vazby), při psaní souborů v pythonu?

0

Otázka

Snažím se tisknout viditelnou zpětnou vazbu pro uživatele v terminálu, zatímco moje aplikace donwloads soubor z webu a napsat to do pevného disku, ale nemohl jsem najít, jak to udělat, čtení dokumentace nebo si to vygooglit.

Tohle je můj kód:

res = requests.get(url_to_file)
with open("./downloads/%s" % (file_name), 'wb') as f:
    f.write(res.content)

Čekal jsem, že vymyslet, jak udělat něco jako toto:

Downloading file ........
 # it keeps going ultil the download is finished and the file writen
Done!

Jsem opravdu strugling ani začít, protože žádná z metod vrátí "slib" (jako v JS).

Každá pomoc by byla velmi vítány! Díky!!!

file promise python
2021-11-24 05:40:54
2

Nejlepší odpověď

3

requests.get ve výchozím nastavení stáhne rozsahu požadovaných prostředků, než se to dostane zpět k vám. Nicméně, to má volitelný argument stream, která umožňuje vyvolat .iter_content nebo .iter_lines na Response objekt. To umožňuje, aby přijaly opatření každé N bajtů (nebo jak každý kus dat přijde), nebo na každém řádku, resp. Něco jako toto:

chunks = []
chunk_size = 16384     # 16Kb chunks
# alternately
# chunk_size = None    # whenever a chunk arrives
res = requests.get(url_to_file, stream=True)
for chunk in res.iter_content(chunk_size):
    chunks.append(chunk)
    print(".", end="")
data = b''.join(chunks)

Tento stále bloků, i když, takže nic dalšího se bude dít. Pokud chcete víc, JavaScript styl, za Grismar komentář, měli byste spustit v Pythonu je asynchronní smyčce. V tom případě navrhuji, pomocí aiohttp spíše než requests, protože je vytvářen s asynchronní styl v mysli.

2021-11-24 06:52:04

Děkuji moc za vaši odpověď! Byl to velmi rychle! haha jsem udělal pochopte a konceptu a jeho dobré vědět, že tam jsou asynchronní funkce v pythonu. Z nějakého důvodu, když jsem se snažil ucházet váš kód, pouze tisknout soubory po žádost skončil. Asi jsem něco chybí...
guilfer
1

Tady je verze, která bude ke stažení soubor do bytearray v samostatném vlákně.

Jak již bylo zmíněno v jiné odpovědi a komentáře, tam jsou jiné alternativs, které jsou vyvíjeny s asynchronní operace v mysli, takže se nemusíte číst příliš do rozhodnutí jít s threadingje to jen prokázat koncept (a kvůli pohodlí, protože to je dodáván s python).

V níže uvedeném kódu, pokud velikost souboru je známo, každý . bude odpovídat 1%. Jako bonus, stáhnout a celkový počet bajtů, které budou vytištěny na začátku řádku (1234 B / 1234567 B). Pokud velikost není známo, nouzový řešení je mít každý . představují kus.

import requests
import threading


def download_file(url: str):
    headers = {"<some_key>": "<some_value>"}
    data = bytearray()
    with requests.get(url, headers=headers, stream=True) as request:
        if file_size := request.headers.get("Content-Length"):
            file_size = int(file_size)
        else:
            file_size = None
        received = 0
        for chunk in request.iter_content(chunk_size=2**15):
            received += len(chunk)
            data += chunk
            try:
                num_dots = int(received * 100 / file_size)
                print(
                    f"({received} B/{file_size} B) "
                    + "." * num_dots, end="\r"
                )
            except TypeError:
                print(".", end="")
        print("\nDone!")

url = "<some_url>"
thread = threading.Thread(target=download_file, args=(url,))
thread.start()
# Do something in the meantime
thread.join()

Mějte na paměti, že jsem nechal zámek na ochranu proti současný přístup k stdout ke snížení hluku. Také jsem vynechal psaní bytarray k souboru na konci (nebo psaní bloky k souboru, jak jsou přijímány, pokud soubor je velký), ale mějte na paměti, že možná budete chtít použít zámek na to, jak dobře, pokud budete číst a/nebo zapisovat do stejného souboru v jiné části skriptu.

2021-11-24 05:57:53

To je awsome! Myslím, že jsem pochopit koncept, ale jsem poměrně nový python a rozhodl jsem se jít na snadný způsob, haha já jsem záložek vaše answaer a jakmile jsem se dozvědět více o řezání závitů jsem si jistý, že bude revesit! Díky moc!
guilfer

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................