2014-12-20 40 views
5

Python 3'teki değişikliklerden biri, normal metin modunda dosyanın sonundan arama yapma yeteneğini kaldırmak olmuştur. Buna genel olarak kabul edilen alternatif nedir?Python 3 dosyasından arama yapın.

piton 2.7 Örneğin ben (-3,2)

Onlar bu yüzden sadece bir PEP bağlantı veren etmeyiniz niye hakkında biraz okudum file.seek girersiniz. 'Rb' kullanarak arama yapmama izin verdiğimi biliyorum, ancak bu metin dosyamın yanlış biçimde okunmasını sağlıyor.

+0

Tek baytlı kodlamalar için verileri her zaman el ile deşifre edebilirsiniz. –

+0

https://docs.python.org/3.1/tutorial/inputoutput.html python 3.1'i kullanmaya devam ediyorsanız, arama hala kullanılabilir –

+0

@IsuruMadusanka: seek tüm Python 3 sürümlerinde mevcuttur. Mevcut olmayan ** sondan itibaren göreceli olarak ** arıyor. 3.1 istisna değildir. –

cevap

5

Python 2'de, dosya verileri okunurken çözülmedi. Python 3. için devre dışıdır neden

Hala yatan tampon üzerinde talep edebilirsiniz, ki bu (sonraki karakter başlamak nereye bilemezsiniz) geriye gitme ve multi-byte kodlamaları iyice karıştırın yok nesne, TextIOBase.buffer attribute aracılığıyla, ama o zaman o anda nerede şimdiki sarıcı artık bilecek gibi yeni TextIOBase sarıcı takın gerekecek: Ben herhangi bir kodlama ve hat boyunca kopyaladığınız

import io 

file.buffer.seek(-3, 2) 
file = io.TextIOWrapper(
    file.buffer, encoding=file.encoding, errors=file.errors, 
    newline=file.newlines) 

bilgileri io.TextIOWrapper() object'a taşıma. Bu kod çözmenin UTF-16, UTF-32, UTF-8 ve diğer çoklu bayt kodekleri için kırılabileceğini göz önünde bulundurun.

Demo:

with open(somefile) as file: 
    # ... 

    file = textio_seek(file, -2, 3) 

    # ... 

bir bağlam yöneticisi olarak dosya nesnesini kullanarak: Bir fayda fonksiyonuna bu sarabilirdiniz

>>> import io 
>>> with open('demo.txt', 'w') as out: 
...  out.write('Demonstration\nfor seeking from the end') 
... 
38 
>>> with open('demo.txt') as inf: 
...  print(inf.readline()) 
...  inf.buffer.seek(-3, 2) 
...  inf = io.TextIOWrapper(inf.buffer) 
...  print(inf.readline()) 
... 
Demonstration 

35 
end 

: olarak

import io 

def textio_seek(fobj, amount, whence=0): 
    fobj.buffer.seek(amount, whence) 
    return io.TextIOWrapper(
     fobj.buffer, encoding=fobj.encoding, errors=fobj.errors, 
     newline=fobj.newlines) 

ve bu kullanmak sadece, orijinal dosya nesnesiyle birlikte çalışır. ence hala orijinal dosya tampon nesnesine eklenir ve bu nedenle dosyayı kapatmak için hala kullanılabilir.