https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str
Łańcuch (string) to uporządkowany ciąg znaków używany do przechowywania informacji tekstowej. W Pythonie 2 znaki odpowiadają bajtom, więc bytes() to alias do str() (Py2.7). W Pythonie 3 string (typ str) zawiera znaki Unikodu (code points), które zamienia się na ciąg bajtów korzystając z ustalonego kodowania. Jeden znak Unikodu może odpowiadać kilku bajtom.
Łańcuchy zaliczane są do niezmiennych sekwencji, czyli nie można ich zmieniać w obszarze przechowywania ich w pamięci. Dostęp do znaków możliwy jest za pomocą offsetu (przesunięcia). Dozwolone są ujemne offsety (odliczanie od końca).
W Pythonie nie ma osobnego typu znakowego jak w języku C. Znakami są po prostu stringi o długości jeden.
Moduły pomocnicze: string, re, itp.
Stałe łańcuchowe mogą być zapisywane z użyciem apostrofów lub znaków cudzysłowu. Dzięki temu możemy wstawiać znak cudzysłowu/apostrofu wewnątrz łańcucha bez specjalnych zabiegów. Wielowierszowe bloki wygodnie jest zapisywać wewnątrz potrójnych znaków, ponieważ zachowywane są końce linii.
+----------------------+-----------------------------+
| Operacja | Znaczenie |
+----------------------+-----------------------------+
| "", '', str() | puste napisy |
| S = "abc" | tworzenie napisu |
| S = str(obiekt) | tworzenie napisu |
| len(S) | długość napisu |
| S1 + S2 | łączenie |
| n * S, S * n | powtarzanie |
| S[i] | indeksowanie |
| S[i:j] | wycinanie |
| S[i:j:k] | wycinanie |
| S2 = S1[:] | kopiowanie |
| S2 = str(S1) | kopiowanie |
| for char in S: pass | iteracja |
| S1 in S2 | zawieranie (bool) |
| S1 not in S2 | |
| S1.count(S2) | liczba wystąpień | (non-overlapping matches!)
| S1.index(S2) | pierwsze wystąpienie |
| max(S), min(S) | największy|najmniejszy znak |
| "%s dom" % "stary" | formatowanie łańcucha |
| "%s %s" % ("a", "b") | |
| S.join(iterable) | sklejanie z napisem |
| S.format(...) | Py2.6+, Py3.x |
| del S | usuwanie napisu |
+----------------------+-----------------------------+
Standard Unikodu przypisuje abstrakcyjnym znakom (characters)
liczby całkowite dodatnie (code points).
String Unikodu jest to ciąg code points.
Reguły transformacji stringu Unikodu na ciąg bajtów jest to
kodowanie.
Najpopularniejsze obecnie kodowanie to UTF-8.
Code point 97 (litera 'a') odpowiada u'\x61' = u'\u0061' = u'\U00000061',
(0)110.0001, jeden bajt w UTF-8.
Code point 257 odpowiada u'\u0101',
(110)0.0100.(10)00.0001, dwa bajty w UTF-8.
(u'\u0101').encode('utf-8') zwraca w Pythonie 2 string '\xc4\x81'.
('\u0101').encode('utf-8') zwraca w Pythonie 3 bytes b'\xc4\x81'.
Code point 8364 (znak euro) odpowiada u'\u20ac',
(1110).0010.(10)00.0010.(10)10.1100, trzy bajty w UTF-8, '\xe2\x82\xac'.
p = 8364 # code point dla znaku Euro (int)
hex(p) # '0x20ac'
char = chr(p) # znak Euro jako string (str)
ascii(char) # '\u20ac' (str), znak zapisany przez cyfry szesnastkowe
utf = char.encode('utf-8') # b'\xe2\x82\xac' (bytes), znak zakodowany
# Zwykłe stringi. W Pythonie 3 zawierają znaki Unikodu.
"pierwszy", 'drugi', "trzeci'x", 'czwarty"y'
"raz" 'dwa' # napisy obok siebie będą sklejone
# Raw strings - napisy ze znakami specjalnymi.
r"raw string\n\t\a"
# Unicode strings (Py2). Nazwa typu to unicode().
unicode('abc')
u"unicode"
# Tworzenie jednego znaku Unikodu (Py2).
unichr(97) # return u'a' = u'\x61' = u'\u0061' = u'\U00000061'
unichr(256) # return u'\u0100'
# Raw Unicode strings (Py2).
ur"raw unicode"
# Potrójne znaki do wielowierszowych bloków.
# Można stosować """ lub '''.
"""
Syntax: nazwa [OPCJE]
-h pomoc
-v wersja
"""
# Korzystanie z odwrotnego ukośnika (backslash).
# Generujemy znaki specjalne lub pozbawiamy jakiś znak
# jego specjalnego znaczenia.
"jeden\"dwa", 'trzy\'cztery' # " lub ' w środku nie kończy stringu
"pole1\tpole2\tpole3" # \t to tabulacja, odstep poziomy
"pierwszy wiersz\ndrugi wiersz"
# \n to newline, znak przejścia do nowego wiersza
"tak pokazujemy ukośnik \\" # \\ to jeden ukośnik (backslash)
# W skrypcie można wykorzystać potrójne znaki do tymczasowego # blokowania (wykomentowania) kodu. X = 1 """ import os # zablokowany kod print(os.getcwd()) """ Y = 2
Dla łańcucha S dozwolone są indeksy od 0 do len(S)-1.
Indeks ujemny S[-n] rozumiany jest jako S[len(S)-n].
S[i] jest łańcuchem o długości jeden.
S[j:k] wycina elementy od S[j] do S[k-1] włącznie, tworząc nowy łańcuch.
S[:k] oznacza S[0:k].
S[j:] oznacza S[j:len(S)].
S[:] daje cały łańcuch.
S[:j] + S[j:] daje cały łańcuch.
# Napisy można porównywać (<, >, ==), nawet trójkami. napis1 = "abc" napis2 = "bcd" napis1 < napis2 "a" > "Z" # owoc = "banan" # Nie wolno podstawić tak jak w C, napisy są niezmienne. # owoc[0] = "s" ERROR! # Trzeba utworzyć nowy string np. poleceniem # nowy_owoc = "s" + owoc[1:] a = "abc" b = "abc" c = a d = a[:] # to samo miejsce w pamięci id(a), id(b), id(c), id(d) # też dla copy.copy() jest to samo miejsce w pamięci # UWAGA Te efekty zachodzą dla krótkich napisów, bo Python # krótkie napisy trzyma w pamięci do późniejszego wykorzystania.
# Napisy są niezmienne (immutable). >>> a = "abc" >>> a[1] = "s" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment >>>
>>> S = "abc" >>> S + "xyz" # konkatenacja 'abcxyz' >>> S # S pozostaje bez zmian 'abc' >>> 3 * S 'abcabcabc' >>> S * 4 'abcabcabcabc' >>> S[::-1] # wycinanie od końca 'cba' >>>
Znak plus (+) czy gwiazdka (*) oznacza co innego dla liczb, a co innego dla napisów. Jest to przykład polimorfizmu w Pythonie.
colors = ["red", "blue", "green", "yellow"]
# Pierwszy sposób dopuszczalny tylko dla kilku składników.
result = ""
for item in colors:
result = result + item
# Prawidłowy sposób. Składnia.
# S.join(iterable), S to separator przy sklejaniu
result = "".join(colors)
Metody dla stringów nie mogą zmienić oryginału, więc zwykle zwracają nowy łańcuch.
dir(str) # lista metod stringów
print(ord("a")) # 97, kod ASCII znaku
print(ord(u"ą)) # 261, ord() działa też dla unikodu w Py2
print(chr(98)) # "b", znak dla danego kodu ASCII
word = "".join(["a","b","c","d","e","f"]) # sklejanie listy znaków lub stringów
print(word) # "abcdef"
word.find("cd") # 2, odnalezienie przesunięcia podłańcucha
word.replace("bc", "xyz") # zastąpienie wystąpień podłańcucha
# Justowanie tekstu.
word = "hej"
word.ljust(6) # "hej "
word.rjust(6) # " hej"
word.center(6) # " hej "
# Usuwanie białych znaków (whitespace).
word = " abc "
word.lstrip() # "abc "
word.rstrip() # " abc"
word.strip() # "abc"
word = "...abc.."
word.strip(".") # "abc"
word = "rAz dWa tRzY"
word.lower() # "raz dwa trzy"
word.upper() # "RAZ DWA TRZY"
word.capitalize() # "Raz dwa trzy"
word.title() # "Raz Dwa Trzy"
word.swapcase() # "RaZ DwA TrZy"
word.startswith("abc") # sprawdzam prefix
word.endswith("abc") # sprawdzam suffix
"abbbbc".count("bb") # wynik 2, a nie 3
# bo nie wlicza się nakładających wystąpień
# Lista wyrazów bez białych znaków.
line = "a\tb c\nd"
line.split() # ['a', 'b', 'c', 'd']
line.split("\t") # ["a", "b c\nd"]
line.splitlines() # ['a\tb c', 'd']
"111".zfill(8) # "00000111"
# Badanie typów znaków w stringu.
S.isalnum()
S.isalpha()
S.isdigit()
S.islower()
S.isupper()
S.isspace()
Jeżeli w Pythonie 2 chcemy sprawdzić, czy obiekt X jest łańcuchem,
korzystamy z wywołania isinstance(X, basestring),
gdzie basestring to klasa bazowa dla
str i unicode (Py2.3+).
W Pythonie 3 korzystamy z wywołania isinstance(X, str),
klasa basestring została usunięta z języka (PEP 3137).
Łańcuchy znaków obsługują zaawansowane operacje formatowania ze znakiem procenta (%) lub metodą format [więcej informacji przy opisie standardowego wyjścia].
W Pythonie 2.7 pojawia się memoryview(object), przy czym obiekt musi wspierać protokół buforowania (buffer protocole). Protokół buforowania dostarcza sposobu na dostęp do wewnętrznych danych obiektu. W zwykłym kodzie pythonowym używa się protokołu buforowania za pomocą klasy memoryview. Obiekty wbudowane wspierające protokół buforowania to str i bytearray (ale nie unicode). Klasa memoryview ma dwie metody tobytes() i tolist(), oraz kilka atrybutów tylko do odczytu.
Za pomocą klasy memoryview można używać i modyfikować duże ilości danych bez ich kopiowania. Dzięki temu dany program używa mniej pamięci i działa szybciej.
>>> v = memoryview('abcefg') # widok obiektu str
>>> v[1] # zwraca str
'b'
>>> v[-1]
'g'
>>> v[1:4] # wycinek zwraca subview
<memory at 0x77ab28>
>>> v[1:4].tobytes() # zwraca bytestring, czyli str
'bce'
>>> v.readonly # czy pamięć jest readonly
True
>>> v.tolist() # zwraca listę int
[97, 98, 99, 101, 102, 103]
>>> data = bytearray('abcefg')
>>> v = memoryview(data)
>>> v.readonly # czy pamięć jest readonly
False
>>> v[0] = 'z' # mutable
>>> data
bytearray(b'zbcefg')
>>> v[2] = 'spam'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot modify size of memoryview object
https://stackoverflow.com/questions/6736771/buffers-and-memoryview-objects-explained-for-the-non-c-programmer Buffers and Memoryview Objects explained for the non-C programmer
https://eli.thegreenplace.net/2011/11/28/less-copies-in-python-with-the-buffer-protocol-and-memoryviews Less copies in Python with the buffer protocol and memoryviews
https://julien.danjou.info/high-performance-in-python-with-zero-copy-and-the-buffer-protocol/ High-Performance in Python with Zero-Copy and the Buffer Protocol (by Julien Danjou)
W Py3 zamiast typów str i unicode występują typy bytes i str, które mają odmienne własności. W Py3 znika basestring (PEP 3137).
bytes(object) zwraca niezmienną (immutable) tablicę bajtów. [W Py2.7 jest to alias do str().]
bytearray(object) zwraca zmienną (mutable) tablicę bajtów. [Istnieje w Py2.7.]
str(object) zwraca niezmienny string mogący zawierać znaki Unikodu. [W Py2 odpowiada mu unicode().]
memoryview(object) tworzy widok obiektu. Obiekt musi wspierać protokół buforowania (buffer protocol), czyli dawać dostęp do bufora obiektu bez robienia kopii. Było wiele zmian w kolejnych wersjach Py3.
Praca w systemie Linux Debian 10, ustawienie locale pl_PL.UTF-8.
# Wprowadzanie tekstu z klawiatury (Py2). >>> a = 'jabłko' # str >>> a 'jab\xc5\x82ko' >>> b = u'jabłko' # unicode >>> b u'jab\u0142ko'
# Wprowadzanie tekstu z klawiatury (Py3). >>> a = 'jabłko' >>> a 'jabłko'