Saturday 2 December 2017

Python read text file as binary options


7. Dane wejściowe i wyjściowe Istnieje kilka sposobów prezentacji danych wyjściowych programu, które można wydrukować w formie czytelnej dla człowieka lub zapisać w pliku do wykorzystania w przyszłości. W tym rozdziale omówimy niektóre z możliwości. 7.1. Formatowanie wyjściowego formatowania Dotychczas napotkaliśmy dwa sposoby zapisywania wartości: wyrażenia expression i polecenie print. (Trzecia metoda polega na użyciu metody write () obiektów plików, do której standardowy plik wyjściowy można odwoływać się jako sys. stdout. Więcej informacji na ten temat znajduje się w podręczniku Library Reference.) Często chcesz uzyskać większą kontrolę nad formatowaniem danych wyjściowych niż po prostu drukowanie wartości rozdzielonych spacjami. Istnieją dwa sposoby formatowania danych wyjściowych. Pierwszym sposobem jest samodzielne wykonanie wszystkich operacji na łańcuchach przy użyciu operacji przecinania i łączenia łańcuchów, aby utworzyć dowolny układ, jaki można sobie wyobrazić. Typy łańcuchów mają kilka metod, które wykonują użyteczne operacje dla dopełniania łańcuchów do danej szerokości kolumny, które zostaną wkrótce omówione. Drugi sposób polega na użyciu metody str. format (). Moduł string zawiera klasę Template, która oferuje jeszcze jeden sposób zamiany wartości na łańcuchy. Oczywiście pozostaje jedno pytanie: w jaki sposób konwertować wartości na łańcuchy Na szczęście Python ma możliwość konwersji dowolnej wartości na ciąg znaków: przekazuje go do funkcji repr () lub str (). Funkcja str () ma na celu zwrócenie reprezentacji wartości, które są czytelne dla człowieka, podczas gdy repr () ma na celu generowanie reprezentacji, które mogą być odczytane przez interpreter (lub wymuszenie wywołania składni, jeśli nie ma równoważnej składni). W przypadku obiektów, które nie mają określonej reprezentacji do spożycia przez ludzi, funkcja str () zwróci tę samą wartość, co repr (). Wiele wartości, takich jak liczby lub struktury, takie jak listy i słowniki, ma tę samą reprezentację przy użyciu dowolnej z tych funkcji. W szczególności ciągi i liczby zmiennoprzecinkowe mają dwie różne reprezentacje. Oto dwa sposoby napisania tabeli kwadratów i sześcianów: (Zauważ, że w pierwszym przykładzie, jedna przestrzeń pomiędzy każdą kolumną została dodana przy okazji drukowania działa: zawsze dodaje spacje między swoimi argumentami.) Ten przykład demonstruje str. rw () Metoda obiektów łańcuchowych, która wyrównuje łańcuch znaków w polu o danej szerokości, wypełniając go spacjami po lewej stronie. Istnieją podobne metody str. ljust () i str. center (). Te metody nic nie zapisują, po prostu zwracają nowy ciąg. Jeśli łańcuch wejściowy jest zbyt długi, nie przycinają go, ale zwracają go niezmienione, co zepsuje układ kolumn, ale jest to zwykle lepsze rozwiązanie niż alternatywa, która polegałaby na wartości. (Jeśli naprawdę chcesz skracać, zawsze możesz dodać operację plastra, jak w x. ljust (n): n.) Istnieje inna metoda, str. zfill (). która nakłada łańcuch liczbowy po lewej stronie z zerami. Rozumie znaki plus i minus: Podstawowe użycie metody str. format () wygląda następująco: nawiasy i znaki w nich (zwane polami formatu) są zamieniane na obiekty przekazywane do metody str. format (). Liczba w nawiasach odnosi się do pozycji obiektu przekazanego do metody str. format (). Jeśli argumenty słów kluczowych są używane w metodzie str. format (), ich wartości są określane za pomocą nazwy argumentu. Argumenty pozycji i słów kluczowych można dowolnie łączyć: 7.2. Odczytywanie i zapisywanie plików open () zwraca obiekt pliku i jest najczęściej używany z dwoma argumentami: open (filename, mode). Pierwszy argument to ciąg zawierający nazwę pliku. Drugi argument to kolejny łańcuch zawierający kilka znaków opisujących sposób, w jaki plik będzie używany. Tryb może być r, gdy plik zostanie odczytany, w tylko do zapisu (istniejący plik o tej samej nazwie zostanie usunięty), a plik otwierający do dołączania jakichkolwiek danych zapisanych do pliku jest automatycznie dodawany do końca. r otwiera plik zarówno do odczytu, jak i zapisu. Argument trybu jest opcjonalny r zostanie przyjęty, jeśli zostanie pominięty. W systemie Windows b dołączony do trybu otwiera plik w trybie binarnym, więc istnieją również tryby takie jak rb. wb. i rb. Python w systemie Windows rozróżnia tekst i pliki binarne, gdy znaki końca linii w plikach tekstowych są automatycznie modyfikowane podczas odczytu lub zapisu danych. Ta "zakulisowa" modyfikacja danych pliku jest w porządku dla plików tekstowych ASCII, ale powoduje uszkodzenie danych binarnych, takich jak w plikach JPEG lub EXE. Zachowaj ostrożność, aby korzystać z trybu binarnego podczas odczytywania i zapisywania takich plików. W systemie Unix nie zaszkodzi dołączyć b do trybu, więc można go używać niezależnie od platformy dla wszystkich plików binarnych. 7.2.1. Metody obiektów plików Reszta przykładów w tej sekcji zakłada, że ​​obiekt pliku o nazwie f został już utworzony. Aby przeczytać zawartość pliku8217s, zadzwoń do f. read (rozmiar). który odczytuje pewną ilość danych i zwraca ją jako ciąg znaków. size jest opcjonalnym argumentem numerycznym. Gdy rozmiar jest pominięty lub ujemny, cała zawartość pliku zostanie odczytana i zwrócony problem, jeśli plik jest dwa razy większy niż pamięć urządzenia. W przeciwnym razie, bajty o największej wielkości są odczytywane i zwracane. Po osiągnięciu końca pliku, f. read () zwróci pusty ciąg (quotquot). f. readline () odczytuje pojedynczą linię z pliku, znak nowej linii (n) znajduje się na końcu łańcucha i jest pomijany tylko w ostatnim wierszu pliku, jeśli plik nie kończy się znakiem nowej linii. To sprawia, że ​​zwracana wartość jest jednoznaczna, jeśli f. readline () zwraca pusty łańcuch, koniec pliku został osiągnięty, a pusta linia jest reprezentowana przez n. ciąg zawierający tylko jeden znak nowej linii. Aby odczytać linie z pliku, możesz zapętlić obiekt pliku. Jest to pamięć wydajna, szybka i prowadzi do prostego kodu: Jeśli chcesz przeczytać wszystkie linie pliku na liście, możesz również użyć listy (f) lub f. readlines (). f. write (string) zapisuje zawartość łańcucha do pliku, zwracając None. Aby napisać coś innego niż ciąg znaków, musi najpierw zostać przekonwertowany na ciąg: f. tell () zwraca liczbę całkowitą, która nadaje plikowi aktualną pozycję pliku, mierzoną w bajtach od początku pliku. Aby zmienić położenie obiektu pliku8217s, użyj f. seek (offset, fromwhat). Pozycja jest obliczana od dodania przesunięcia do punktu odniesienia, punkt odniesienia jest wybierany przez od tego z tego argumentu. Wartość od 0 oznacza od początku pliku, 1 używa aktualnej pozycji pliku, a 2 używa końca pliku jako punktu odniesienia. fromwhat można pominąć i przyjmuje wartość domyślną 0, wykorzystując początek pliku jako punkt odniesienia. Kiedy skończysz z plikiem, wywołaj funkcję f. close (), aby ją zamknąć i zwolnić zasoby systemowe pobierane przez otwarty plik. Po wywołaniu f. close (). próby użycia obiektu pliku automatycznie zakończą się niepowodzeniem. Dobrą praktyką jest użycie słowa kluczowego with przy obchodzeniu się z obiektami plików. Ma to tę zaletę, że plik jest poprawnie zamknięty po zakończeniu działania pakietu, nawet jeśli w drodze zostanie zgłoszony wyjątek. Jest on również znacznie krótszy niż wypisywanie odpowiedników try-finally blocks: Obiekty plików mają kilka dodatkowych metod, takich jak isatty () i truncate (), które są rzadziej używane, aby zapoznać się z kompletnym przewodnikiem po obiektach plików, odwołując się do Library Reference. 7.2.2. Zapisywanie danych strukturalnych za pomocą json Strings można łatwo zapisać i odczytać z pliku. Liczby wymagają nieco więcej wysiłku, ponieważ metoda read () zwraca tylko ciągi, które będą musiały zostać przekazane do funkcji takiej jak int (). która pobiera ciąg jak 123 i zwraca jego wartość liczbową 123. Gdy chcesz zapisać bardziej złożone typy danych, takie jak zagnieżdżone listy i słowniki, parsowanie i serializacja ręczna staje się skomplikowana. Zamiast ciągłego pisania i debugowania kodu użytkownika, aby zapisać skomplikowane typy danych w plikach, Python pozwala używać popularnego formatu wymiany danych o nazwie JSON (JavaScript Object Notation). Standardowy moduł o nazwie json może przyjmować hierarchie danych Pythona i konwertować je na reprezentacje ciągów, proces ten nazywa się serializacją. Rekonstrukcja danych z reprezentacji łańcuchowej nazywana jest deserializacją. Między serializacją a deserializacją łańcuch reprezentujący obiekt mógł zostać zapisany w pliku lub danych lub przesłany przez połączenie sieciowe do odległej maszyny. Format JSON jest powszechnie używany przez nowoczesne aplikacje, aby umożliwić wymianę danych. Wielu programistów już go zna, co czyni go dobrym wyborem dla interoperacyjności. Jeśli masz obiekt x. możesz zobaczyć jego reprezentację ciągów JSON za pomocą prostego wiersza kodu: Inny wariant funkcji dumps (), zwany dump (). po prostu serializuje obiekt do pliku. Jeśli więc f jest obiektem pliku otwartym do zapisu, możemy to zrobić: Aby ponownie zdekodować obiekt, jeśli f jest obiektem pliku, który został otwarty do odczytu: Ta prosta technika serializacji może obsługiwać listy i słowniki, ale serializuje dowolne wystąpienia klasowe w JSON wymaga trochę dodatkowego wysiłku. Odniesienie do modułu json zawiera wyjaśnienie tego. pickle - moduł pickle W przeciwieństwie do JSON. pickle to protokół, który pozwala na serializację dowolnie złożonych obiektów Pythona. Jako taki jest specyficzny dla Pythona i nie może być używany do komunikacji z aplikacjami napisanymi w innych językach. Domyślnie jest to również niebezpieczne: deserializacja danych pickle pochodzących z niezaufanego źródła może spowodować wykonanie niepożądanego kodu, jeśli dane zostały wykonane przez wykwalifikowanego atakującego. Sugeruje to chrispy: Zauważ, że instrukcja with nie jest dostępna w wersjach Pythona poniżej 2.5. Aby użyć go w wersji 2.5, musisz go zaimportować: w wersji 2.6 nie jest to potrzebne. W Pythonie 3 jest nieco inny. Nie będziemy już otrzymywać surowych znaków ze strumienia w trybie bajtowym, ale bajtów, dlatego musimy zmienić warunek: lub jak mówi benhoyt, pomiń nie równe i wykorzystaj fakt, że b ocenia na false. Dzięki temu kod jest zgodny między wersjami 2.6 i 3.x bez żadnych zmian. Oszczędziłoby to również przed zmianą warunku, jeśli przejdziesz z trybu bajtowego do tekstu lub odwrotnie. Aby odczytywać plik po jednym bajcie na raz (ignorując buforowanie), można użyć wbudowanej dwuargumentowej iter (wywoływalnej, wartownika): wywołuje plik file. read (1), dopóki nie zwróci nic b (pusty bytestring). Pamięć nie rośnie nieograniczona w przypadku dużych plików. Możesz przekazać buffering0, aby otworzyć (). aby wyłączyć buforowanie, gwarantuje to, że tylko jeden bajt jest czytany dla iteracji. with - statement zamyka plik automatycznie, w tym przypadku, gdy kod pod spodem wywołuje wyjątek. Pomimo domyślnego domyślnego buforowania wewnętrznego nadal nie jest możliwe przetwarzanie jednego bajtu na raz. Na przykład, heres narzędzie blackhole. py, które zjada wszystko, co jest podane: 1,5 GB z domyślnym bufsize na moim komputerze i tylko 7,5 MB, jeśli bufsize1. Oznacza to, że jest 200 razy wolniej czytać jeden bajt na raz. Weź to pod uwagę, jeśli możesz przerobić przetwarzanie, aby użyć więcej niż jednego bajtu na raz i jeśli potrzebujesz wydajności. mmap pozwala traktować plik jednocześnie jako obiekt bytearray i plik. Może służyć jako alternatywa do ładowania całego pliku w pamięci, jeśli potrzebujesz dostępu do obu interfejsów. W szczególności można iterować po jednym bajcie na pliku odwzorowanym w pamięci przy użyciu zwykłego dla - loop: mmap obsługuje notację plastra. Na przykład mmi: ilen zwraca len bajtów z pliku rozpoczynającego się na pozycji i. Protokół kontekstowego menedżera nie jest obsługiwany przed Pythonem 3.2, musisz w tym przypadku jawnie wywołać mm. close (). Iterowanie po każdym bajcie przy użyciu mmap zużywa więcej pamięci niż file. read (1). ale mmap jest o rząd wielkości szybszy. Odpowiedzi 16 listopada 13 o 4:47 Podsumowując wszystkie genialne punkty chrispy, Skurmedel, Ben Hoyt i Peter Hansen, byłoby to optymalne rozwiązanie do przetwarzania pliku binarnego po jednym bajcie na raz: Dla wersji Pythona 2.6 i wyższych, ponieważ: bufory Pythona wewnętrznie - nie trzeba czytać fragmentów zasada DRY - nie powtarzaj linii odczytu z instrukcją zapewnia, że ​​czysty bajt zamykania pliku ocenia na false, gdy nie ma więcej bajtów (nie gdy bajt wynosi zero) Lub użyj rozwiązania JF Sebastians dla lepszej prędkości Lub jeśli chcesz go jako funkcję generatora, jak pokazano przez codeape: odpowiedział Sep 6 13 o 7:55 JFSebastian - masz 100 poprawne - prawdopodobnie znacznie szybciej ndash Holger Bille 9 maja 16 o 8:12 Jako połączona odpowiedź mówi, czytanie przetwarzania jednego bajtu na raz jest wciąż wolne w Pythonie, nawet jeśli odczyty są buforowane. Wydajność można drastycznie poprawić, jeśli kilka bajtów na raz może być przetworzonych, jak w przykładzie w połączonej odpowiedzi: 1,5 GB vs. 7,5 MB. ndash J. F. Sebastian May 9 16 at 11:49 Jeśli masz dużo danych binarnych do przeczytania, możesz rozważyć moduł struct. Jest to udokumentowane jako konwersja między typami C i Python, ale oczywiście bajty są bajtami, a to, czy zostały utworzone jako typy C, nie ma znaczenia. Na przykład, jeśli twoje dane binarne zawierają dwie 2-bajtowe liczby całkowite i jedną 4-bajtową liczbę całkowitą, możesz je odczytać w następujący sposób (przykład zaczerpnięty z dokumentacji struktury): Możesz znaleźć to wygodniej, szybciej lub jedno i drugie niż jawnie zapętlać się zawartość pliku. odpowiedział 1 lipca 15 o 11:24 Czytanie pliku binarnego w Pythonie i zapętlenie każdego bajtu Zróbmy plik: Teraz pozwala iterować nad nim, używając flagi rb (tryb odczytu, tryb bajtów). Zauważ, że wielokrotność dla pętli nie zwiększa złożoności (która pozostaje O (n)) - tak po prostu leniwie iterujesz po pliku - linia po linii. Spowoduje to zapętlenie każdego bajtu kodu, bez żadnych hacky. read (1). Jest to o wiele więcej Pythonicznego i naturalnego niż pętla while i komplikacja, którą widziałem w innych odpowiedziach tutaj. Buforowane czytanie Jeśli masz duże pliki bez nowych linii, możesz chcieć buforować czytanie. Python 2.7 wymaga io. open, aby to uzyskać: I mamy teraz buforowany czytnik: wbudowana funkcja open Python 3s to 2s io. open. Jak czytać i zapisywać pliki w Pythonie Kiedy już programujesz w języku Python poza najbardziej trywialnymi programami, Zazwyczaj wymagane jest odczytywanie danych i zapisywanie danych w plikach, które istnieją poza samym programem. Python zapewnia łatwe mechanizmy dostępu i modyfikowania określonych plików przy użyciu standardowych funkcji, które są częścią podstawowego języka. Otwórz pliki w Pythonie Zdecyduj o polityce użytkowania. Musisz wiedzieć, czy musisz przeczytać lub zapisać w pliku, zanim będziesz mógł otworzyć plik. Otwórz tylko plik z prawdziwymi uprawnieniami i nie otwieraj pliku w trybie do odczytu i zapisu, kiedy musisz tylko z niego odczytać. Zapobiegnie to przypadkowym zapisom do pliku, do którego nie powinieneś pisać. Zdecyduj, czy chcesz używać trybu ASCII, czy binarnego. Jeśli czytasz tekst, będziesz chciał użyć trybu ASCII. Jeśli czytasz dane binarne, użyj trybu binarnego. Ten tryb przetłumaczy zakończenia linii na tryb używany przez twój system operacyjny. Utwórz łańcuch trybu. Pierwszy znak to tryb odczytu lub zapisu. Jeśli chcesz otworzyć w trybie binarnym, dodaj quotbquot na końcu łańcucha. Na przykład, aby odczytywać w trybie ASCII, łańcuch trybów byłby quotquot i aby pisać w trybie binarnym, łańcuch trybów byłby quotwbquot. Otwórz plik za pomocą funkcji otwierania. Zapisz wynikowy obiekt pliku w zmiennej. Na przykład: f open (quotfilenamegosherequot, quotrquot) Czytaj z plików w Pythonie Iteruj po wszystkich liniach. Obiekt pliku może być używany jako kolekcja z pętlą quotquotquot. Możesz iterować po wszystkich liniach w pliku (wspólna akcja) z instrukcją for. dla linii in f: print line Przejdź do określonego punktu w pliku. Pliki nie zawsze są czytane sekwencyjnie, więc często trzeba szukać określonego punktu w pliku przed odczytaniem z pliku. Możesz to zrobić za pomocą metody seek obiektu pliku. Szukaj do 100 bajta f. seek (100) Szukaj do 10 bajtów z bieżącego bajtu f. seek (10, 1) Czytaj dane binarne z pliku. Korzystając z metody read obiektu pliku, można odczytać dowolną liczbę bajtów z pliku. Odczytaj 16 bajtów z pliku buf f. read (16) Napisz do Pythona Pliki Zapisz dane do pliku. Jeśli plik jest otwarty w trybie zapisu, możesz zapisać do niego dane ASCII lub dane binarne. Odbywa się to za pomocą metody zapisu obiektu pliku. f. write (quotTo jest tekst) Napisz obiekty do pliku. Jeśli chcesz zapisać wewnętrzny stan obiektu, możesz go zlizywać. Aby podnieść obiekt, musisz najpierw zaimportować moduł pikle. Po tym możesz zająć się niemal dowolnym obiektem za pomocą funkcji pickle. dump. import pickle. dump (anyobject, f) Zamknij plik. Po zakończeniu zapisu musisz zamknąć plik. Zapewnia to, że wszystkie bufory są opróżniane, a plik nie jest zablokowany, aby inne programy mogły uzyskać do niego dostęp. Odbywa się to za pomocą metody close obiektu pliku.

No comments:

Post a Comment