Unicode vs UTF-8 zamieszanie w Pythonie / Django?

Natknąłem się na ten fragment w Django tutorial:

Modele Django mają domyślną metodę str (), która wywołuje unicode () i konwertuje wynik na UTF-8 bajtów. Oznacza to, że unicode(p) zwróci ciąg znaków Unicode, a str (p) zwróci zwykły ciąg znaków zakodowany jako UTF-8.

Teraz jestem zdezorientowany, ponieważ afaik Unicode nie jest żadną konkretną reprezentacją, więc czym jest "ciąg Unicode" w Pythonie? Czy to czyli UCS-2? Googling pojawił się ten "Python Unicode Tutorial" który śmiało stwierdza

Unicode jest dwubajtowym kodowaniem, które obejmuje wszystkie popularne na świecie systemy zapisu.

Co jest po prostu złe, czy jest? Wiele razy byłem zdezorientowany przez zestaw znaków i problemy z kodowaniem, ale tutaj jestem całkiem pewien, że dokumentacja, którą czytam, jest zdezorientowana. Czy ktoś wie co się dzieje w Pythonie kiedy daje mi "ciąg Unicode"?

Author: Hanno Fietz, 2008-08-22

5 answers

Co to jest "ciąg Unicode" w Pythonie? Czy to oznacza UCS-2?

Ciągi Unicode w Pythonie są przechowywane wewnętrznie jako UCS-2 (Reprezentacja o stałej długości 16-bitowa, prawie taka sama jak UTF-16) lub UCS-4/UTF-32 (reprezentacja o stałej długości 32-bitowa). Jest to opcja w czasie kompilacji; w Windows jest to zawsze UTF-16, podczas gdy wiele dystrybucji Linuksa ustawia UTF-32 ('wide mode') dla swoich wersji Pythona.

Generalnie nie powinno cię to obchodzić: zobaczysz Unicode kod-wskazuje jako pojedyncze elementy w ciągach i nie będzie wiadomo, czy są one przechowywane jako dwa lub cztery bajty. Jeśli jesteś w kompilacji UTF - 16 i musisz obsługiwać znaki poza podstawową płaszczyzną wielojęzyczną, będziesz robił to źle, ale to wciąż bardzo rzadkie, a użytkownicy, którzy naprawdę potrzebują dodatkowych znaków, powinni kompilować szerokie Kompilacje.

Zwykły błąd, czy jest?

Tak, to całkiem złe. Szczerze mówiąc uważam, że tutorial jest raczej stary, prawdopodobnie przed szerokie ciągi znaków Unicode, jeśli nie Unicode 3.1 (wersja, która wprowadziła znaki spoza podstawowej płaszczyzny wielojęzycznej). [1]}istnieje dodatkowe źródło nieporozumień wynikające z przyzwyczajenia systemu Windows do używania terminu "Unicode" w odniesieniu do kodowania UTF-16LE używanego wewnętrznie przez NT. Ludzie z Microsoftlandu często kopiują ten nieco mylący zwyczaj.
 48
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 10:11:53

W międzyczasie zrobiłem wyrafinowane badania, aby zweryfikować, czym jest wewnętrzna reprezentacja w Pythonie, a także jakie są jego granice. "The Truth About Unicode in Python " jest bardzo dobrym artykułem, który cytuje bezpośrednio od programistów Pythona. Wygląda na to, że wewnętrzna reprezentacja to albo UCS-2 albo UCS-4 w zależności od przełącznika czasu kompilacji. Jon, to nie jest UTF-16, ale twoja odpowiedź i tak postawiła mnie na dobrej drodze, dzięki.

 8
Author: Hanno Fietz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 13:50:39

Python przechowuje Unicode jako UTF-16. str () zwróci reprezentację UTF-8 łańcucha UTF-16.

 0
Author: Jonathan Works,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 12:03:47

From Wikipedia na UTF-8:

UTF-8 (8-bitowy format transformacji UCS/Unicode) jest kodowaniem znaków o zmiennej długości dla Unicode. Jest w stanie reprezentować dowolny znak w standardzie Unicode, jednak początkowe kodowanie kodów bajtowych i przypisywanie znaków dla UTF-8 jest kompatybilne wstecznie z ASCII. Z tych powodów stale staje się preferowanym kodowaniem dla poczty elektronicznej, stron internetowych[1] i innych miejsc, w których przechowywane są znaki lub / align = "left" /

Więc, to jest w dowolnym miejscu od jednego do czterech bajtów w zależności od tego, który znak chcesz reprezentować w sferze Unicode.

Z Wikipedii Na Unicode:

W informatyce, Unicode jest standardem branżowym pozwalającym komputerom konsekwentnie reprezentować i manipulować tekstem wyrażonym w większości światowych systemów pisma .

Jest więc w stanie reprezentować większość (ale nie wszystkie) światowych systemów pisma.

Mam nadzieję, że to pomoże :)

 -1
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 12:10:14

Więc co to jest "ciąg Unicode" w Python?

Python 'wie', że Twój ciąg znaków jest Unicode. Stąd jeśli zrobisz regex na nim, będzie wiedział, który jest charakter, a który nie jest itp, co jest naprawdę pomocne. Jeśli zrobiłeś strlen, to również da prawidłowy wynik. Jako przykład, jeśli nie liczysz łańcuchów na Hello, otrzymasz 5 (nawet jeśli jest to Unicode). Ale jeśli zrobiłeś liczbę znaków obcego słowa i ten ciąg nie był ciągiem Unicode, to będziesz miał znacznie większy wynik. Pythong używa informacji z bazy danych znaków Unicode do identyfikacji każdego znaku w ciągu znaków Unicode. Mam nadzieję, że to pomoże.

 -2
Author: Ravi Chhabra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 14:01:34