2013-10-25 16 views
5

Python'da for line in file yapmanın bir yolu olmasını istiyorum; burada satır sonu, istediğim herhangi bir dize olacak şekilde yeniden tanımlanır. Bunu söylemenin başka bir yolu da kayıtlardan ziyade dosyadan kayıt okumak istiyorum; Okuma çizgileri yapmak için eşit derecede hızlı ve kullanışlı olmasını istiyorum.Python'daki dosyadan özel ayırıcı tarafından sonlanan kayıtlar nasıl okunur?

Perl'in $/ giriş kayıt ayırıcısını ayarlama veya java'da Scanner kullanarak python eşdeğeridir. Bu mutlaka for line in file'u kullanmak zorunda değildir (özellikle yineleyici bir dosya nesnesi olmayabilir). Sadece hafızaya çok fazla veri okumayı engelleyen bir şey.

Ayrıca bakınız: Add support for reading records with arbitrary separators to the standard IO stack

cevap

8

Python 2.x file nesne veya readline için özel bir ayırıcı belirtmek sağlayan Python 3.3 io sınıfları, hiçbir şey yoktur. (for line in file nihayetinde readline ile aynı kodu kullanıyor.)

Ancak bunu kendiniz oluşturmak oldukça kolaydır. Örneğin:


def delimited(file, delimiter='\n', bufsize=4096): 
    buf = '' 
    while True: 
     newbuf = file.read(bufsize) 
     if not newbuf: 
      yield buf 
      return 
     buf += newbuf 
     lines = buf.split(delimiter) 
     for line in lines[:-1]: 
      yield line 
     buf = lines[-1] 
Burada eylem bunun bir aptal örnek:

>>> s = io.StringIO('abcZZZdefZZZghiZZZjklZZZmnoZZZpqr') 
>>> d = delimited(s, 'ZZZ', bufsize=2) 
>>> list(d) 
['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr'] 

bunu özellikle 3'te sağ hem ikili ve metin dosyaları için almak istiyorum. x, biraz daha zor. Ama eğer sadece biri ya da diğeri (ve bir dil ya da diğeri) için çalışmak zorundaysa, bunu görmezden gelebilirsiniz.

Benzer şekilde, Python 3.x kullanıyorsanız (veya Python 2.x'te io nesnelerini kullanıyorsanız) ve bir arabellek koymak yerine BufferedIOBase'da zaten korunmakta olan arabelleklerden yararlanmak istiyorsanız Tamponun üstü, bu çok zor. io dokümanları her şeyin nasıl yapılacağını açıklıyor… ama herhangi bir basit örnek bilmiyorum, bu yüzden bu sayfanın en az yarısını okumak ve gerisini silmek zorunda kalacaksınız. (Tabii ki, sadece ham dosyaları doğrudan kullanabilirsiniz ... ama eğer unicode sınırlayıcılarını bulmak istiyorsanız…)

+1

OP izleyicinin tüm izleyiciyi okuduktan sonra, Douglas Alan çok benzer bir tarif yayınlamış gibi görünüyor. Tartışma 5 yıl] (http://bugs.python.org/issue1152248#msg109117). Onun daha iyi olmasını seviyorum çünkü girdi satırsonunu sadece onu atmak yerine bir çıktı satırsonuna dönüştürmenize izin veriyor… ama benimkileri benimkilendirmek yerine, sadece bağlantıyı bırakacağım. – abarnert

+0

Bağlı olanın bir başka avantajı, akış kapatıldığında tamponun kalanını döndürmesidir. – jozxyqk

+0

@jozxyqk: Bununla ne demek istediğinden emin değilim. Bu versiyon, EOF'de tamponun kalanını verir. (Dosya gerçekten sizin altından kapatılmış ve bir istisna oluşturmuşsa, bu istisnayı istediğinizi varsayalım - sonuçta, tüm nokta "dosyada satır için": ancak farklı bir sınırlayıcı ile çalışmaktır.) – abarnert

İlgili konular