2013-04-21 28 views
7

Mam plik tekstowy z pierwszą linią znaków Unicode i wszystkie inne linie w ASCII. Próbuję odczytać pierwszy wiersz jako jedną zmienną, a wszystkie pozostałe jako drugą. Jednak, kiedy użyć następującego kodu:Open() i codecs.open() w Pythonie 2.7 zachowują się dziwnie inaczej

# -*- coding: utf-8 -*- 
import codecs 
import os 
filename = '1.txt' 
f = codecs.open(filename, 'r3', encoding='utf-8') 
print f 
names_f = f.readline().split(' ') 
data_f = f.readlines() 
print len(names_f) 
print len(data_f) 
f.close() 
print 'And now for something completely differerent:' 
g = open(filename, 'r') 
names_g = g.readline().split(' ') 
print g 
data_g = g.readlines() 
print len(names_g) 
print len(data_g) 
g.close() 

pojawia się następujący komunikat:

<open file '1.txt', mode 'rb' at 0x> 
28 

7 

And now for something completely differerent: 

<open file '1.txt', mode 'r' at 0x017875A0> 

28 

77 

Jeśli nie używam readlines() odczytuje cały plik, nie tylko pierwsze 7 linii zarówno w codecs.open() i open().

Dlaczego takie rzeczy się zdarzają? Dlaczego program codecs.open() odczytuje plik w trybie binarnym, pomimo dodania parametru "r"?

Upd: Jest to oryginalny plik: http://www1.datafilehost.com/d/0792d687

+1

'codecs.open()' * ma *, aby otworzyć plik w trybie binarnym, aby zapobiec bajtom, które * wyglądają * tak, jak nowe linie są interpretowane przed dekodowaniem. Nowe znaki to UTF-16 to '\ n \ x00' lub' \ x00 \ n' na przykład. –

+0

Byłoby pomocne, gdybyś udostępnił swój oryginalny plik wejściowy. –

+0

@MartijnPieters: Dziękuję za odpowiedź! Oto plik: http://wikisend.com/download/406380/1.txt – Kriattiffer

Odpowiedz

15

Ponieważ stosowane .readline()pierwszy plik codecs.open() wypełniło linebuffer; kolejne wywołanie do .readlines() zwraca tylko zbuforowane linie.

Jeśli zadzwonisz .readlines()ponownie, reszta linii zwrócone są:

>>> f = codecs.open(filename, 'r3', encoding='utf-8') 
>>> line = f.readline() 
>>> len(f.readlines()) 
7 
>>> len(f.readlines()) 
71 

Prace wokół jest nie mieszać .readline() i .readlines():

f = codecs.open(filename, 'r3', encoding='utf-8') 
data_f = f.readlines() 
names_f = data_f.pop(0).split(' ') # take the first line. 

Takie zachowanie jest naprawdę błąd; twórcy Pythona są tego świadomi, patrz: issue 8260.

Inną opcją jest użycie io.open() zamiast codecs.open(); Biblioteka io jest tym, czego Python 3 używa do implementacji wbudowanej funkcji open() i jest dużo bardziej odporny i wszechstronny niż moduł codecs.

+0

Wspaniały! Sprawdziłem i rozmiary 'code'' '. Join (data_f)'' code' i 'code' ''. Join (names_f)' code' są prawie równe. – Kriattiffer