Python'da bir dosya yazarken "noktalar" (veya başka tür geri bildirimler) nasıl yazdırılır?

0

Soru

Uygulamam web'den bir dosya yüklerken ve sabit sürücüye yazarken terminalde kullanıcı için görünür bir geri bildirim yazdırmaya çalışıyorum, ancak dokümantasyonu okuyarak veya google'da arama yaparak bunu nasıl yapacağımı bulamadım.

Bu benim kodum:

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

Böyle bir şeyi nasıl yapacağımı bulmayı umuyordum.:

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

Başlamak için bile gerçekten uğraşıyorum, çünkü yöntemlerden hiçbiri bir "söz" döndürmüyor (js'de olduğu gibi).

Herhangi bir yardım çok takdir edilecektir! Teşekkürler!

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

En iyi cevabı

3

requests.get varsayılan olarak, istenen kaynağın tamamını size geri dönmeden önce indirir. Ancak, isteğe bağlı bir bağımsız değişkeni vardır stream, hangi çağırmak için izin verir .iter_content veya .iter_lines on the Response nesne. Bu, sırasıyla her N baytta (veya her veri parçası geldiğinde) veya her satırda işlem yapmanızı sağlar. Bunun gibi bir şey:

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)

Yine de bu hala engelliyor, bu yüzden başka hiçbir şey olmayacak. JavaScript stilinden daha fazlasını istiyorsanız, Grismar'ın yorumuna göre, Python'un async döngüsü altında çalışmalısınız. Bu durumda, kullanmanızı öneririmaiohttp ziyade requests, async stili göz önünde bulundurularak oluşturulduğu gibi.

2021-11-24 06:52:04

Cevabınız için çok teşekkür ederim! Çok hızlıydı! haha, undestand ve konsepti yaptım ve python'da eşzamansız özellikler olduğunu bilmek güzel. Bazı nedenlerden dolayı kodunuzu doğrulamaya çalıştığımda, Dosyaları yalnızca istek bittikten sonra yazdırdı. Muhtemelen bir şeyi kaçırıyorum...
guilfer
1

İşte dosyayı bir dosyaya indirecek bir sürüm bytearray ayrı bir iş parçacığında.

Diğer cevaplarda ve yorumlarda belirtildiği gibi, zaman uyumsuz işlemler göz önünde bulundurularak geliştirilen başka alternatifler de vardır, bu nedenle karar verme kararını çok fazla okumayın threading bu sadece kavramı göstermek içindir (ve python ile birlikte geldiği için kolaylık nedeniyle).

Aşağıdaki kodda, dosyanın boyutu biliniyorsa, her . %1'e karşılık gelecektir. Bonus olarak, indirilen ve toplam bayt sayısı satırın başında aşağıdaki gibi yazdırılır (1234 B / 1234567 B). Boyut bilinmiyorsa, geri dönüş çözümü her birine sahip olmaktır . bir parçayı temsil et.

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()

Eşzamanlı erişime karşı korumak için kilidi dışarıda bıraktığımı unutmayın. stdout gürültüyü azaltmak için. Ayrıca yazmayı bıraktım bytarray sonunda dosyalamak (veya dosya büyükse parçaları alındıkları gibi dosyaya yazmak), ancak komut dosyanızın başka bir bölümünde aynı dosyayı okuyup/veya yazarsanız bunun için de bir kilit kullanmak isteyebileceğinizi unutmayın.

2021-11-24 05:57:53

Bu müthiş! Sanırım kavramı anlıyorum, ama python için oldukça yeniyim ve kolay yoldan gitmeye karar verdim haha Cevabınızı yer imlerine ekliyorum ve iş parçacığı hakkında daha fazla şey öğrenir öğrenmez kesinlikle gözden geçireceğim! Çok teşekkürler!
guilfer

Diğer dillerde

Bu sayfa diğer dillerde

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