Co dokładnie robią flagi łańcuchowe " u " i " r " i czym są surowe literały łańcuchowe?

Zadając to pytanie , zdałem sobie sprawę, że nie wiem zbyt wiele o surowych strunach. Jak na kogoś, kto twierdzi, że jest trenerem Django, to jest do bani.

Wiem, co to jest kodowanie, i wiem, co robi u'' sam, ponieważ mam to, co jest Unicode.

  • Ale co dokładnie robi r''? Co to za struna daje?

  • A przede wszystkim, co do cholery robi ur''?

  • Wreszcie, czy istnieje jakiś niezawodny sposób, aby wrócić z Unicode ciąg do prostego surowego łańcucha?

  • A tak przy okazji, jeśli Twój system i Kod edytora tekstu są ustawione na UTF-8, to czy u'' rzeczywiście coś robi?

Author: wim, 2010-01-17

6 answers

Nie ma tak naprawdę żadnego " raw string "; istnieją surowe string literały, które są dokładnie literałami ciągu oznaczonymi 'r' przed cytatem otwierającym.

"raw string literal" jest nieco inną składnią Dla ciągu literalnego, w którym ukośnik wsteczny, \, jest brany jako znaczenie " tylko ukośnik wsteczny "(z wyjątkiem sytuacji, gdy pojawia się tuż przed cytatem, który w przeciwnym razie zakończyłby literal) - brak "sekwencji specjalnych" do reprezentowania nowych linii, tabulatorów, spacji wstecznych, form-feeds, i tak dalej. W normalnych literałach ciągów, każdy ukośnik wsteczny musi być podwojony, aby uniknąć przyjęcia jako początek sekwencji escape.

Ten wariant składni istnieje głównie dlatego, że składnia wzorców wyrażeń regularnych jest ciężka z odwrotnymi ukośnikami (ale nigdy na końcu, więc powyższa klauzula "except" nie ma znaczenia) i wygląda nieco lepiej, gdy unikasz podwajania każdego z nich -- to wszystko. Zyskał również pewną popularność wyrażania natywnych ścieżek plików Windows (z ukośniki zamiast zwykłych ukośników, jak na innych platformach), ale to bardzo rzadko potrzebne (ponieważ zwykłe ukośniki działają dobrze również na Windows) i niedoskonałe (ze względu na klauzulę" except " powyżej).

r'...' jest łańcuchem bajtów (w Pythonie 2.* ), ur'...' jest ciągiem Unicode (ponownie, w Pythonie 2.* ), a każdy z pozostałych trzech rodzajów cytowania również produkuje dokładnie te same typy ciągów (tak na przykład r'...', r'''...''', r"...", r"""...""" są ciągami bajtowymi itd.).

Nie wiem co masz na myśli " going back " - nie ma wewnętrznych kierunków do tyłu i do przodu, ponieważ nie ma surowego typu string , jest to tylko alternatywna składnia do wyrażania zupełnie normalnych obiektów string, bajtów lub unicode, jak mogą być.

I tak, w Pythonie 2.*, u'...' jest oczywiście zawsze różny od tylko '...' -- pierwszy jest ciągiem unicode, drugi jest ciągiem bajtów. W jakim kodowaniu literał może być wyrażony jest całkowicie ortogonalny problem.

Np. consider (Python 2.6):

>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34

Obiekt Unicode oczywiście zajmuje więcej miejsca w pamięci (bardzo mała różnica dla bardzo krótkiego ciągu, oczywiście ;-).

 511
Author: Alex Martelli,
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
2017-04-29 20:22:55

Istnieją dwa typy łańcuchów w Pythonie: tradycyjny typ str i nowszy typ unicode. Jeśli wpiszesz literał Bez u z przodu otrzymasz stary typ str, który przechowuje 8-bitowe znaki, a z u z przodu otrzymasz nowszy typ unicode, który może przechowywać dowolny znak Unicode.

r w ogóle nie zmienia typu, po prostu zmienia sposób, w jaki literał Łańcuchowy jest interpretowany. Bez r, ukośniki są traktowane jako znaki ucieczki. Z r, ukośniki są traktowane jako dosłowne. Tak czy siak, typ jest taki sam.

ur jest oczywiście ciągiem Unicode, gdzie ukośniki są literalnymi ukośnikami, a nie częścią kodów specjalnych.

Możesz spróbować przekonwertować Łańcuch Unicode na stary za pomocą funkcji str(), ale jeśli są jakieś znaki unicode, które nie mogą być reprezentowane w starym łańcuchu, otrzymasz wyjątek. Możesz je najpierw zastąpić znakami zapytania, jeśli chcesz, ale oczywiście spowodowałoby to te znaki są nieczytelne. Nie zaleca się używania typu str, jeśli chcesz poprawnie obsługiwać znaki unicode.

 142
Author: Mark Byers,
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
2014-04-28 18:51:54

'surowy łańcuch' oznacza, że jest przechowywany tak, jak się wydaje. na przykład, '\' jest tylko ukośnikiem odwrotnym zamiast ucieczki.

 33
Author: xiaolong,
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
2012-03-06 01:21:38

Przedrostek "u" oznacza, że wartość ma typ unicode zamiast str.

Nieprzetworzone literały łańcuchowe, z przedrostkiem "r", wymawiają wszystkie sekwencje escape wewnątrz nich, więc len(r"\n") wynosi 2. Ponieważ unikają sekwencji escape, nie można zakończyć ciągu literalnego pojedynczym ukośnikiem wstecznym: nie jest to prawidłowa Sekwencja escape (np. r"\").

"Raw" nie jest częścią typu, jest tylko jednym ze sposobów reprezentacji wartości. Na przykład "\\n" i r"\n" są identycznymi wartościami, podobnie jak 32, 0x20, oraz 0b100000 są identyczne.

Możesz mieć surowe literały znaków unicode:

>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2

Kodowanie pliku źródłowego po prostu określa sposób interpretacji pliku źródłowego, nie wpływa to na wyrażenia lub typy w inny sposób. Jednak zaleca się, aby unikać kodu, w którym kodowanie inne niż ASCII zmieniłoby znaczenie:

Pliki używające ASCII (lub UTF-8, dla Pythona 3.0) nie powinny mieć pliku cookie kodującego. Latin - 1 (lub UTF-8) powinien być używany tylko wtedy, gdy komentarz lub docstring musi podać nazwę autora, która wymaga Latin-1; w przeciwnym razie, użycie \X, \ u lub \ u Escape jest preferowanym sposobem na dołączenie danych nie-ASCII do literałów łańcuchowych.

 28
Author: ,
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
2010-01-17 16:55:23

Wyjaśnię to po prostu: W Pythonie 2 można przechowywać ciąg znaków w 2 różnych typach.

Pierwszy to ASCII czyli typ str w Pythonie używa 1 bajtu pamięci. (256 znaków, przechowuje głównie angielskie alfabety i proste symbole)

Drugi typ to UNICODE czyli Unicode typ w Pythonie, używa 2 bajtów pamięci. (65536 znaków, więc obejmuje to wszystkie znaki wszystkich języków na ziemi)

Domyślnie python będzie preferuj str type ale jeśli chcesz zapisać ciąg w Unicode type możesz umieścić u Przed tekstem jak u'text ' lub możesz to zrobić przez wywołanie unicode ('text')

Więc u jest tylko krótkim sposobem na wywołanie funkcji do cast str do unicode . To jest to!

Teraz część r , umieszczasz ją przed tekstem, aby powiedzieć komputerowi, że tekst jest tekstem surowym, ukośnik wsteczny nie powinien być znakiem specjalnym. r '\n ' nie utworzy nowego znaku linii. To zwykły tekst zawierający 2 znaki.

Jeśli chcesz przekonwertować str na unicode i umieścić tam również surowy tekst, użyj ur, Ponieważ RU spowoduje błąd.

Teraz ważna część:

Nie można zapisać jednego ukośnika używając r , jest to jedyny wyjątek. Więc ten kod spowoduje błąd: r'\'

Aby zapisać ukośnik wsteczny (tylko jeden) musisz użycie '\\'

Jeśli chcesz zapisać więcej niż 1 znak, możesz nadal używać rJak r'\\' będzie produkować 2 ukośniki zgodnie z oczekiwaniami.

Nie znam powodu, dla którego r nie działa z jednym backslash storage, ale powód nie jest jeszcze opisany przez nikogo. Mam nadzieję, że to błąd.

 16
Author: off99555,
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
2017-01-10 16:23:38

Może to oczywiste, może nie, ale możesz zrobić ciąg '\' przez wywołanie x=chr(92)

x=chr(92)
print type(x), len(x) # <type 'str'> 1
y='\\'
print type(y), len(y) # <type 'str'> 1
x==y   # True
x is y # False
 2
Author: Bomba Ps,
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
2017-05-15 07:37:24