Ten artykuł jest lekturą obowiązkową dla tych, co często obsługują pliki Unicode (dotyczy to również innych kodowań) w swojej codziennej pracy. Obsługa plików Unicode dla praktykującego przetwarzanie języka naturalnego jest koszmarem, szczególnie jeśli używasz systemu operacyjnego Windows. Wyobraź sobie frustrację, gdy napotkasz błędy w kodowaniu lub dekodowaniu, jak na przykład:
UnicodeEncodeError: 'mbcs' codec can't decode characters in position
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position
Większość czasu, takie błędy nie mówią zbyt wiele, chyba że jesteś weteranem w tej dziedzinie. Być może pytacie, dlaczego musimy kodować i dekodować znaki. Zacznijmy od prostego wyjaśnienia Unicode. W oparciu o oficjalną dokumentację Pythona, Unicode (Universal Coded Character Set) jest specyfikacją, która ma na celu wymienienie każdego znaku używanego przez języki ludzkie i nadanie każdemu znakowi unikalnego kodu. Specyfikacje Unicode są stale aktualizowane w celu dodawania nowych języków i symboli.
Kodowanie i dekodowanie służą jako sposób mapowania znaków z tekstu do bajtów lub odwrotnie. Dzięki temu możemy przenosić je między komputerami i wykorzystywać je w życiu codziennym. To się komplikuje, gdy masz do czynienia z różnymi systemami operacyjnymi. Ponadto, różne języki mają własne zestawy znaków, które mogą być wyświetlane tylko przy użyciu odpowiednich czcionek. Dla uproszczenia, pomyśl o tym jak o tłumaczeniu obcego znaku na taki, którą maszyny zrozumieją. W tym artykule, będziemy badać niektóre metody, które mogą być użyte w obsłudze plików Unicode w Pythonie. Zacznijmy od dostępnych trybów i standardowych kodowań.
Najbezpieczniejszym sposobem otwarcia pliku jest użycie takoż z instrukcją 'with'. Automatycznie zamknie dla nas plik, zapobiegając wszelkim problemom, które mogą się pojawić.
with open('name.txt') as f:
f.readlines()
Domyślnym trybem jest 'rt', który odnosi się do odczytu i pliku tekstowego. Możesz pisać używając następującego kodu:
with open('name.txt', 'w') as f:
f.write('Hello world!')
Powyższy kod nadpisze i wyczyści plik. W niektórych przypadkach można preferować tryb 'a' zamiast 'w'. Poniższa lista przedstawia wszystkie dostępne tryby pracy:
Możesz połączyć niektóre z trybów. Jak podano w oryginalnej dokumentacji, dla binarnego dostępu do odczytu/zapisu, tryb 'w+b' otwiera i czyści plik do 0 bajtów. R+b" otwiera plik bez czyszczenia go.
Aby określić kodowanie w Pythonie, możesz po prostu podać inny argument podczas inicjalizacji menedżera kontekstu. Musisz to określić podczas czytania lub pisania znaków Unicode. Poniższy przykład pokazuje właściwy sposób dołączenia tekstu Unicode do istniejącego pliku:
with open('name.txt', 'a', encoding='utf8') as f:
f.write('你好!')
Jeśli nie jesteś pewien, którego kodowania użyć, po prostu dodaj utf8 i sprawdź, czy nie wystąpił błąd. W większości przypadków UTF-8 jest wystarczająco dobry do kodowania i dekodowania znaków. Są jednak przypadki, w których należy użyć innego kodowania. Sprawdź poniższy link, aby dowiedzieć się więcej o dostępnych kodowaniach. Co jeśli nie masz pojęcia, jakie kodowanie jest używane w twoim pliku? Przejdźmy do następnej części, aby dowiedzieć się jak.
Osobiście wolę używać Notepad++, aby zobaczyć zawartość pliku. Jeśli otworzysz plik z Notepad++, zobaczysz typ kodowania używany w prawym dolnym rogu interfejsu użytkownika.
Przykładowy plik, w którym zastosowano kodowanie UTF-8.
Kodowanie można zmienić za pomocą menu Kodowanie. Przyjmuje on szeroki zakres najczęściej używanych kodowań.
Obraz pokazujący menu rozwijane po kliknięciu menu kodowania
Jeśli kiedykolwiek miałeś problemy z tym, że nie jesteś w stanie przekonwertować pliku do innego kodowania lub nie możesz odczytać niektórych kodowań, nawet jeśli podałeś je poprawnie, możesz spróbować następującej głupiej, ale działającej metody.
W większości przypadków będzie to automatycznie zamieniać wszystkie znaki na nowe kodowanie. Należy pamiętać, że może dojść do utraty danych, jeśli znak nie może być konwertowany na podstawie nowego kodowania.
Jeśli kiedykolwiek znajdziesz się w sytuacji, w której nie uda Ci się zidentyfikować kodowania, a znaki okażą się czymś nieznanym, możesz spróbować zmodyfikować argument dotyczący błędów, aby rozwiązać problem:
with open('name.txt', 'r', encoding='utf8', errors='ignore') as f:
f.readlines()
Argument błędu odnosi się do sposobu postępowania z błędami kodowania i dekodowania. Należy pamiętać, że ten argument nie może być używany w trybie binarnym. Dostępne są następujące błędy:
Jeśli używasz wiersza poleceń w systemie operacyjnym Windows, przez większość czasu będzie miał problem z wyświetlaniem znaków Unicode:
Polecenie wyświetlające bełkot znaków.
Aby rozwiązać ten problem, musimy ustawić właściwą czcionkę.
Właściwości czcionki wiersza poleceń
Ta część jest nieco trudna, zwłaszcza gdy używasz niektórych modułów Pythona, takich jak pandas. Powiedzmy, że masz następującą ścieżkę do pliku w języku innym niż angielski:
file_path = 'C:\path\to\数据分析\data.csv'
Próba odczytania pliku przez read_csv rzuci błędem po prostu dlatego, że ścieżka do pliku zawiera znaki Unicode. Nie jest to problem, jeśli używasz wbudowanej funkcji open() w Pythonie. Aby rozwiązać ten problem, musimy najpierw otworzyć plik, a następnie przekazać go do funkcji read_csv:
with open(file_path, 'r', encoding='utf-8') as f:
df = pd.read_csv(f, encoding='utf-8')
Powtórzmy to, co opisaliśmy w tym poradniku. Najpierw dowiedzieliśmy się, jak ważne jest używanie menedżera kontekstu (instrukcja 'with') podczas czytania i pisania plików. Zostaliśmy zapoznani z listą dostępnych trybów i standardowych kodowań, które mogą być używane w Pythonie. Teraz wiemy, że możemy wykorzystać istniejący edytor tekstu, taki jak Notepad++, aby zapewnić nam wgląd w kodowanie i strukturę pliku wejściowego. Jeśli są jakieś znaki o nieznanym kodowaniu, możemy sobie z tym poradzić poprzez argument obsługi błędów przekazywany w czasie inicjalizacji. Dla użytkowników systemu Windows istnieje możliwość modyfikacji czcionki w wierszu poleceń w celu prawidłowego wyświetlania tekstu Unicode. Na koniec nauczyliśmy się otwierać plik przed użyciem modułu pandas do odczytu dowolnego zbioru danych. Dzięki za lekturę i życzę miłego dnia!