Nasza strona używa cookies. Dowiedz się więcej o celu ich używania i zmianie ustawień w przeglądarce. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Unicode w Pythonie - triki i wskazówki

Ng Wai Foong AI Engineer / YOOZOO GAMES
Jak korzystać z context managera, Nopedad++, oraz różnych czcionek Windowsa, by nie dopuścić do żadnych nieprzyjemnych niespodzianek z Unicode.
Unicode w Pythonie - triki i wskazówki

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ń.

Odczytywanie lub zapisywanie plików za pośrednictwem context managera

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:

  • r: otwarte do odczytu (domyślnie)
  • w: otwarte do zapisu, najpierw czyści plik
  • x: otwarte wyłącznie do tworzenia, rzuci błąd, jeżeli plik już istnieje.
  • a: otwarte do zapisu, dołączane do końca pliku, jeśli taki istnieje
  • b: tryb binarny
  • t: tryb tekstowy (domyślnie)
  • +: otwórz plik dysku w celu aktualizacji (odczytywania i zapisywania)

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.

Standardowe kodowania w Pythonie

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.

Sprawdzenie typu kodowania poprzez Notepad++

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.

  1. Utwórz pusty plik tekstowy z żądanymi kodowaniami.
  2. Skopiuj całą zawartość z oryginalnego pliku.
  3. Wklej go do nowego pliku i zapisz go.

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.

Postępowanie ze znakami w nieznanym kodowaniu

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:

  • strict: aby rzucić wyjątek ValueError, jeśli występuje błąd kodowania. Domyślna wartość None ma ten sam efekt.
  • ignore: ignoruje błędy. Należy pamiętać, że ignorowanie błędów kodowania może prowadzić do utraty danych.
  • replace: powoduje wstawienie zastępczego znacznika (takiego jak "?"), jeżeli dane nie są prawidłowe.
  • substituteescape: reprezentuje wszelkie błędne bajty jako punkty w Unicode Private Use Area w zakresie od U+DC80 do U+DCFF. Te prywatne punkty kodowania zostaną następnie zamienione z powrotem na te same bajty, gdy ten sam sposób obsługi błędów zostanie użyty do zapisu danych. Jest to przydatne w przypadku przetwarzania plików w nieznanym kodowaniu.
  • xmlcharreflace: jest obsługiwany tylko podczas zapisu do pliku. Znaki nieobsługiwane przez kodowanie są zastępowane odpowiednim odniesieniem do znaków XML &#nnn;.
  • backslashreplace: zastępuje zniekształcone dane przez sekwencje specjalne Pythona z odwrotnym ukośnikiem.
  • namereplace: (również obsługiwane tylko podczas pisania) zastępuje znaki nieobsługiwane przez sekwencje specjalne \N{...}.

Wyświetlanie znaków Unicode w wierszu poleceń

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ę.

  1. Kliknij prawym przyciskiem myszy na górnym menu i kliknij właściwości.
  2. Kliknij na menu czcionek.
  3. Modyfikuj czcionkę do żądanej czcionki, która może wyświetlać znak. Na przykład, można użyć czcionki KaiTi do renderowania znaków chińskich.

Właściwości czcionki wiersza poleceń

Otwarcie ścieżki do pliku ze znakami Unicode - dotyczy read_csv przez moduł pandas.

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')

 

Wniosek

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!

Odniesienia

  1. https://docs.python.org/3.5/library/functions.html#open
  2. https://docs.python.org/3.7/library/codecs.html#standard-encodings

    Oryginalny artykuł w języku angielskim można przeczytać tutaj.

Masz coś do powiedzenia?

Podziel się tym z 120 tysiącami naszych czytelników

Dowiedz się więcej
Rocket dog