2010-10-26 13 views
9

Piszę serię instrukcji SQL do pliku przy użyciu Pythona. Ciąg szablon wygląda tak:Python file.write tworzenie dodatkowego powrotu karetki

store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 

Piszę do pliku tak:

for line in source: 
    line = line.rstrip() 
    fields = line.split('\t') 
    script.write(store_insert % tuple(fields)) 
    script.write(os.linesep) 

Jednak w uzyskanej mocy, widzę \ r \ r \ n na końcu każdego linii, a nie \ r \ n, jak się spodziewałam. Czemu?

+1

Formatowanie tekstu "%" jest już stare; preferowanym idiomem jest 'str.format' =) – katrielalex

+4

Czy otworzyłeś plik w trybie tekstowym lub binarnym? Z jakiego systemu operacyjnego korzystasz? – AndiDog

+0

Windows, i właśnie zrobiłem otwarty (plik, "r") – Chris

Odpowiedz

20

\n jest konwertowane na os.linesep dla plików otwartych w trybie tekstowym. Więc kiedy napiszesz os.linesep do pliku trybu tekstowego w systemie Windows, napiszesz \r\n, a \n zostanie przekonwertowany, co spowoduje \r\r\n.

Zobacz także the docs:

Nie używaj os.linesep jako terminator wiersza podczas zapisywania plików otwartych w trybie tekstowym (domyślnie); zamiast tego użyj pojedynczego "\ n" na wszystkich platformach.

+0

+1! Tak naprawdę nie dzieje się to dla mnie (Win7), może jest to zależne od systemu Windows? – katrielalex

+0

Używam również systemu Windows 7, ale to wyjaśnia. +1 i odpowiedz! – Chris

0

patrz open (DOC)

Ponadto średnia fopen() Wartości w trybie może być 'U' lub 'rU'. Python jest zwykle zbudowany z uniwersalną obsługą newline; dostarczenie "U" otwiera plik jako plik tekstowy, ale linie mogą być zakończone przez jedną z następujących konwencji: konwencja końca linii Unix '\ n', konwencja Macintosh '\ r' lub konwencja Windows '\ r \ n '. Wszystkie te reprezentacje zewnętrzne są postrzegane jako "\ n" przez program Python. Jeśli Python jest zbudowany bez obsługi uniwersalnej linii nowej, tryb z literą "U" jest taki sam jak tryb zwykłego tekstu. Zwróć uwagę, że tak otwierane obiekty plików mają również atrybut o nazwie newlines, który ma wartość None (jeśli nie widać jeszcze żadnych linii), '\ n', '\ r', '\ r \ n' lub krotkę zawierającą wszystkie Widoczne typy nowych linii.

+0

Co z tego? Uniwersalny tryb nowego wiersza służy tylko do czytania. – AndiDog

+0

@AndiDog: Myślę, że to, co mówi, to to, że kiedy otwiera plik z otwartym ('', 'r') po tym, jak napisał na nim, widzi \ r \ r \ n i myśli, że napisał tylko " \ r \ n '(Windows), więc powiedziałem mu, że kiedy otworzy swój plik open() doda automatycznie \ r \ n do swoich danych, więc' \ r \ n '+' \ r \ n '=' \ r \ r \ n ',' \ n 'jest usunięty Czy chcesz, abym opracował więcej ??? – mouad

+1

Nie Tak naprawdę używam oddzielnego pliku wyjściowego otwartego z otwartym (plik, "w"). Zmiana na otwarcie (plik, "wb") naprawiła problem, ale nie jestem do końca pewien, czy rozumiem, dlaczego dobrze znaleziono – Chris

1

działa na mnie:

>>> import tempfile 
>>> tmp = tempfile.TemporaryFile(mode="w+") 
>>> store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 
>>> lines = ["foo\t\t"] 
>>> for line in lines: 
...  line = line.rstrip() 
...  fields = line.split("\t") 
...  tmp.write(store_insert % tuple(fields)) 
...  tmp.write(os.linesep) 
... 
>>> tmp.seek(0) 
>>> tmp.read() 
"\tinsert stores (storenum, ...) values ('foo', ...)\r\n" 

Czy na pewno jest to kod, który jest uruchomiony, że os.linesep jest to, co myślę, że jest, etc?

3

Pliki tekstowe mają różne zakończenia linii w różnych systemach operacyjnych, ale wygodnie jest pracować z ciągami, które mają spójny znak końca linii. Python dziedziczy konwencję od C używania '\n' jako znaku kończącego linię uniwersalną i polegając na funkcjach odczytu i zapisu plików, aby wykonać konwersję, jeśli to konieczne. Funkcje odczytu i zapisu wiedzą o tym, jeśli plik został otwarty w domyślnym trybie text. Jeśli dodasz znak b do łańcucha znaków podczas otwierania pliku, tłumaczenie to zostanie pominięte.

3

W Pythonie 3

os.open() wprowadza nowy parametr newline który pozwala określić łańcuch, który każde wystąpienie \n zostanie przetłumaczony.

Podanie pustego argumentu ciągu znaków newline='' wyłącza tłumaczenie, pozostawiając nowy znak bez zmian. Dotyczy tylko trybu tekstowego.

From the documentation

Na wyjściu, jeżeli znak nowej linii jest Brak jakichkolwiek znaków '\ n' napisane są tłumaczone na domyślny układ separatora linii, os.linesep. Jeśli "nowa linia" jest , to nie ma tłumaczenia. Jeśli nowa linia jest jedną z pozostałych dopuszczalnych wartości, wszystkie znaki \ n 'są tłumaczone na podany ciąg znaków .

+0

W przypadku użycia i niektórych opracowań zobacz [tutaj] (http://stackoverflow.com/questions/43528959/python-3-how-to-pass-binary-file-as-text-without-saving- first) – RolfBly

Powiązane problemy