Ako vytlačiť "bodky" (alebo iný druh spätnej väzby) pri písaní súbor v jazyku python?

0

Otázka

Ja som snaží vytlačiť viditeľné spätnú väzbu pre používateľa v termináli, zatiaľ čo moje aplikácie donwloads súbor z webu a napíšte ho na pevný disk, ale nemohol som nájsť, ako to urobiť, čítanie dokumentácie alebo som to.

Toto je môj kód:

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

Čakal som, že prísť na to, ako urobiť niečo ako toto:

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

Som naozaj strugling aj na začiatku, pretože žiadna z metód, vráti "sľub" (ako v JS).

Akákoľvek pomoc bude veľmi apreciated! Vďaka!

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

Najlepšiu odpoveď

3

requests.get štandardne stiahne rozsahu požadovaných zdrojov pred tým, ako sa dostane späť k vám. Avšak, to má voliteľný argument stream, ktorá vám umožňuje vyvolať .iter_content alebo .iter_lines na Response objekt. To vám umožňuje konať každý N bajt (alebo, ako každý kus údaje príde), alebo na každý riadok, resp. Niečo ako 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 blokov, takže nič iné sa deje. Ak chcete viac JavaScript štýl, za Grismar komentár, mali by ste spustiť pod Python to async slučky. V tom prípade navrhujem, pomocou aiohttp skôr ako requests, ako je vytvorený s async štýl v mysli.

2021-11-24 06:52:04

Ďakujem veľmi pekne za vašu odpoveď! Bolo to veľmi rýchlo! haha som undestand a koncept a jeho dobré vedieť, že existujú async funkcie v jazyku python. Z nejakého dôvodu, keď som sa snažil aply váš kód, To len tlačené súbory po žiadosti skončili. Asi som niečo chýba...
guilfer
1

Tu je verzia, ktorá sa stiahnuť súbor do bytearray v samostatnom vlákne.

Ako už bolo spomenuté v iných odpovede a pripomienky, existujú aj iné alternativs, ktoré sú vyvinuté s asynchrónnej operácie v pamäti, takže sa nemusíte čítať príliš do rozhodnutia ísť s threadingje to len na preukázanie pojem (a preto, pohodlie, pretože prichádza s python).

V nižšie zákonníka, ak veľkosť súboru je známe, každý . bude zodpovedať 1%. Ako bonus, stiahnutý a celkový počet bajtov, ktoré sa budú tlačiť na začiatku riadok (1234 B / 1234567 B). Ak veľkosť nie je známe, núdzové riešenie je mať každý . predstavujú 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()

Robiť udržať v pamäti, že som vynechal zámok na ochranu proti simultánny prístup k stdout na zníženie hluku. Ja som tiež vynechané, písať bytarray ak chcete súbor na konci (alebo písať kúsky do súboru, ako sú prijaté, ak súbor je veľký), ale majte na pamäti, že budete chcieť použiť zámok na tom, ako dobre, ak budete čítať a/alebo píšte na rovnaký súbor v akejkoľvek inej časti skriptu.

2021-11-24 05:57:53

Že je awsome! Myslím, že chápem pojem, ale ja som celkom nový python a rozhodol som sa ísť jednoduchý spôsob, ako haha ja som bookmarking vaše answaer a hneď, ako som sa dozvedieť sa viac o threading som si istá, chcel revesit to! Ďakujeme!
guilfer

V iných jazykoch

Táto stránka je v iných jazykoch

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