Boş bir dosyayı okurken neden "Pickle - EOFError: Girdi kalmadı" mesajı alıyorum?


109

Kullanmaya çalışırken ilginç bir hata alıyorum Unpickler.load(), işte kaynak kodu:

open(target, 'a').close()
scores = {};
with open(target, "rb") as file:
    unpickler = pickle.Unpickler(file);
    scores = unpickler.load();
    if not isinstance(scores, dict):
        scores = {};

İşte traceback:

Traceback (most recent call last):
File "G:\python\pendu\user_test.py", line 3, in <module>:
    save_user_points("Magix", 30);
File "G:\python\pendu\user.py", line 22, in save_user_points:
    scores = unpickler.load();
EOFError: Ran out of input

Okumaya çalıştığım dosya boş. Bu hatayı nasıl önleyebilirim ve bunun yerine boş bir değişken alabilirim?


Dosyayı kapatma
Alkesh Mahajan

İlk satır open(...).close()dosyanın var olduğundan emin olmak için buradadır
Magix

Yanıtlar:


127

Önce dosyanın boş olmadığını kontrol ederim:

import os

scores = {} # scores is an empty dict already

if os.path.getsize(target) > 0:      
    with open(target, "rb") as f:
        unpickler = pickle.Unpickler(f)
        # if file is not empty scores will be equal
        # to the value unpickled
        scores = unpickler.load()

Ayrıca open(target, 'a').close()kodunuzda hiçbir şey yapmaz ve kullanmanız gerekmez ;.


open (hedef, 'a'). close () dosyanın var olduğundan emin olmak için burada ;-) + ;Kullanmam gerekmiyor ama C'den geldim ve ;satırlarımın sonunda kullanmamak ağlamamı sağlıyor TT
Magix

tamam, ama sorun durumu gereksiz, sanırım sadece bir emri alacaksınız, boş bir dosya olup olmadığını kontrol etmek yeterli olacaktır
Padraic Cunningham

dahası, dosyanın boş olmadığını kontrol etmek, her zaman onu çözebileceğim anlamına gelmez ... bir istisna ortaya koyarım ... Bu yüzden cevabınızın en iyi olmadığını, hatta kötü olmadığını düşündüğüm için.
Magix

2
bir yakalamak EOF exceptionsizi diğer tüm olası hatalardan kurtarmaz.
Padraic Cunningham

1
os modülünü kullanarak bir dosyanın var olup olmadığını kontrol edebilirsiniz, her seferinde bir dosyayı açıp kapatmaktan daha iyi olabilir.
Padraic Cunningham

131

Buradaki cevapların çoğu, EOFError istisnalarının nasıl yönetileceğiyle ilgiliydi; bu, turşu nesnenin boş olup olmadığından emin değilseniz gerçekten kullanışlıdır.

Ancak, turşu dosyasının boş olmasına şaşırırsanız, bunun nedeni dosya adını 'wb' veya dosyanın üzerine yazmış olabilecek başka bir mod aracılığıyla açmış olmanız olabilir.

Örneğin:

filename = 'cd.pkl'
with open(filename, 'wb') as f:
    classification_dict = pickle.load(f)

Bu turşu dosyasının üzerine yazacaktır. Bunu kullanmadan önce yanlışlıkla yapmış olabilirsiniz:

...
open(filename, 'rb') as f:

Ve sonra EOFError'ı aldım çünkü önceki kod bloğu cd.pkl dosyasının üzerine yazdı.

Jupyter'da veya konsolda (Spyder) çalışırken genellikle okuma / yazma kodunun üzerine bir sarmalayıcı yazarım ve ardından sarmalayıcıyı çağırırım. Bu, yaygın okuma-yazma hatalarını önler ve aynı dosyayı travmalarınız boyunca birden çok kez okuyacaksanız biraz zaman kazandırır.


43
However, if you're surprised that the pickle file is empty, it could be because you opened the filename through 'wb' or some other mode that could have over-written the fileBu, +1
Neb

10
Ben sadece bunu yaptım; bu notu gerçekten takdir ediyorum (tek olmadığıma sevindim!)
zlipp

8
ayrıca daha önce "wb" ile üzerine yazmış. +1
gebbissimo

5
Bazen apaçık olan hiç açık değildir! Teşekkürler :)
jerpint

dosya kilitleme gerekliliği - Bu cevap birçok kişiye yardımcı olur, dosyayı yazmaya açıkken okumaya çalışıyordum.
aspiring1

8

Gördüğünüz gibi, bu aslında doğal bir hata ..

Bir Unpickler nesnesinden okumak için tipik bir yapı şu şekilde olacaktır ..

try:
    data = unpickler.load()
except EOFError:
    data = list()  # or whatever you want

EOFError basitçe yükseltilir, çünkü boş bir dosya okuyordu, sadece Dosyanın Sonu anlamına geliyordu ..


6

Turşu dosyasının boş olması çok muhtemeldir.

Kodu kopyalayıp yapıştırıyorsanız, bir turşu dosyasının üzerine yazmak şaşırtıcı derecede kolaydır.

Örneğin, aşağıdaki bir turşu dosyası yazar:

pickle.dump(df,open('df.p','wb'))

Ve yeniden açmak için bu kodu kopyalanan ancak değişime unutursanız 'wb'için 'rb'o zaman dosyanın üzerine olacaktır:

df=pickle.load(open('df.p','wb'))

Doğru sözdizimi

df=pickle.load(open('df.p','rb'))

1
Son iki kod örneği değiştirilmeli, değil mi?
Daniello

@Daniello yaptım. Teşekkür ederim. Revize edildi.
user2723494

3
if path.exists(Score_file):
      try : 
         with open(Score_file , "rb") as prev_Scr:

            return Unpickler(prev_Scr).load()

    except EOFError : 

        return dict() 

2
Hellow ve Stackoverflow'a hoş geldiniz. Bu kodu biraz açıklar mısınız lütfen?
Alexander

2

Bu istisnayı yakalayabilir ve oradan istediğinizi geri alabilirsiniz.

open(target, 'a').close()
scores = {};
try:
    with open(target, "rb") as file:
        unpickler = pickle.Unpickler(file);
        scores = unpickler.load();
        if not isinstance(scores, dict):
            scores = {};
except EOFError:
    return {}

10
Bununla ilgili sorun, bozuk dosyaları sessizce gizleyecek olmasıdır.
Ross Ridge

0

Dosyaları açma modunun 'a' veya başkalarının 'a' alfabesine sahip olmasının da üzerine yazma nedeniyle hata yapacağını unutmayın.

pointer = open('makeaafile.txt', 'ab+')
tes = pickle.load(pointer, encoding='utf-8')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.