Podsekcje

 
3. Nieformalne wprowadzenie do Pythona

W poniższych przykładach wejście i wyjście rozróżnione zostało poprzez obecność znaków zachęty (">>> " i "... "): aby powtórzyć przykład, trzeba przepisać wszystko za znakiem zachęty; linie, które nie zaczynają się nim, są wyjściem (odpowiedziami) interpretera.

Uwaga! Pojawienie się po raz drugi znaku zachęty oznacza, że trzeba wprowadzić pusty wiersz. Wtedy następuje koniec instrukcji wielowierszowej.

Wiele przykładów w tym podręczniku, nawet te wprowadzone w linii poleceń, zawierają komentarze. W Pythonie komentarz rozpoczyna się od znaku "#" i ciągnie się aż do końca fizycznego wiersza. Komentarz może pojawić się na początku linii lub kończyć instrukcję,, lecz nie może być zawarty w literale ciągu znaków. Znak «hash» ("#") w ciągu znaków jest po prostu zwykłym znakiem, jednym z wielu tego ciągu.

Trochę przykładów:

# to jest pierwszy komentarz
POMYJE = 1                 # a to jest drugi komentarz
                         # ... uch, a to trzeci!
LANCUCH = "# To nie jest komentarz. To jest łańcuch znaków."

 
3.1 Używanie Pythona jako kalkulatora

Wypróbujmy parę prostych poleceń Pythona. Uruchom interpreter i poczekaj na pojawienie się pierwszego znaku zachęty ">>>". (Nie powinno to zająć dużo czasu).

 
3.1.1 Liczby

Interpreter działa jak prosty kalkulator: można wpisać wyrażenie do niego, a on wypisze jego wartość. Składnia wyrażenia jest prosta: operator +, -, * i / działają jak w wielu innych językach programowania (np. Pascal lub C); nawiasy można użyć do grupowania. Na przykład:

>>> 2+2
4
>>> # To jest komentarz
... 2+2
4
>>> 2+2  # a to jest komentarz w tej samej linii co kod instrukcji
4
>>> (50-5*6)/4
5
>>> # Dzielenie całkowite zwraca liczbę zaokrągloną w dół
... 7/3
2
>>> 7/-3
-3

Podobnie jak w C, znak równości ("=") jest używany do przypisania wartości do zmiennej. Przypisanie do zmiennej nie jest wypisywane przez interpreter:

>>> szerokosc = 20
>>> wysokosc = 5*9
>>> szerokosc * wysokosc
900

Wartość może być przypisana jednocześnie paru zmiennym:

>>> x = y = z = 0  # Zero x, y i z
>>> x
0
>>> y
0
>>> z
0
Python implementuje oczywiście arytmetykę zmiennoprzecinkową, a operatory z operandami typów mieszanych przekształcają operandy całkowite w zmiennoprzecinkowe:

>>> 4 * 2.5 / 3.3
3.0303030303
>>> 7.0 / 2
3.5
Liczby zespolone są również wbudowane--części urojone zapisywane są z przyrostkiem "j" lub "J". Liczby zespolone z niezerową częścią rzeczywistą zapisywane są jako "(real+imagj)" lub mogą być stworzone za pomocą funkcji "complex(real, imag)".

>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0,1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)
Liczby zespolone są zawsze reprezentowane jako dwie zmiennoprzecinkowe liczby, odpowiednio część rzeczywista i urojona. Aby wydobyć je z liczby urojonej z, należy użyć z.real i z.imag.

>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5
Funkcje konwersji z liczby zmiennoprzecinkowej do całkowitej (float(), int() i long()) nie działają dla liczb urojonych -- nie ma poprawnego sposobu na przekształcenie liczby zespolonej w rzeczywistą. Użyj abs(z), aby uzyskać jej moduł (jako liczbę zmienno przecinkową) lub z.real, aby uzyskać część rzeczywistą.

>>> a=1.5+0.5j
>>> float(a)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use e.g. abs(z)
>>> a.real
1.5
>>> abs(a)
1.58113883008
(TypeError: nie można przekształcić zespolonej do zmiennoprzecinkowej; użyj np. abs(z))

W trybie interaktywnym, ostatnio wydrukowane wyrażenie przypisywane jest do zmiennej _. Oznacza to, że jeśli używa się Pythona jako biurkowego kalkulatora, niejako łatwym staje się kontynuowanie obliczeń,, jak w poniższym przykładzie:

>>> podatek = 17.5 / 100
>>> cena = 3.50
>>> cena * podatek
0.6125
>>> cena + _
4.1125
>>> round(_, 2) # zaokrągla do dwóch miejsc po przecinku
4.11

Zmienna ta powinna być traktowana przez użytkownika jak tylko do odczytu. Nie warto wprost zapisywać (przypisywać) coś do niej--stworzy się inną, niezależną lokalną zmienną z tą samą nazwą przykrywającą wbudowaną zmienną o tych magicznych właściwościach.

 
3.1.2 Ciągi znaków czyli napisy

Oprócz liczb Python może również manipulować ciągami znaków, które można wyrazić na parę sposobów. Mogą one być objęte pojedynczym lub podwójnym cudzysłowem:

>>> 'zepsute jaja'
'zepsute jaja'
>>> 'A\'propos'
"A'propos"
>>> "A'propos"
"A'propos"
>>> '"Tak," powiedział.'
'"Tak," powiedział.'
>>> "\"Tak,\" powiedział."
'"Tak," powiedział.'
>>> '"A\'propos," powiedziała.'
'"A\'propos," powiedziała.'

Napisy mogą rozciągać się na wiele wierszy. Znaki nowej linii mogą zostać zacytowane za pomocą znaków ukośnika:

hello = "Jest to raczej długi ciąg znaków zawierający\n\
kilka linii tekstu, tak jak robisz to w C.\n\
    Zauważ, że znaki spacji i znaki białe na początku linii\
 są znaczące.\n"
print hello

spowoduje pojawienie się zaraz za tym:

Jest to raczej długi ciąg znaków zawierający
kilka linii tekstu, tak jak robisz to w C.
    Zauważ, że znaki spacji i znaki białe na początku linii są znaczące.

Równie dobrze ciągi znaków mogą być ujęte w pary potrójnych cudzysłowów: """ lub '''. Końce linii nie muszą być w takim przypadku cytowane,, lecz zostaną dosłownie włączone do ciągu.

print """
Użytkowanie: cienias [OPCJE]
     -h                        Pokaż ten opis poleceń
     -H nazwaserwera      Nazwa serwera, z którym chcesz się połączyć
"""

powoduje następującą odpowiedź interpretera:

Użytkowanie: cienias [OPCJE]
     -h                        Pokaż ten opis poleceń
     -H nazwaserwera      Nazwa serwera, z którym chcesz się połączyć

Interpreter drukuje wynik działań na napisach w ten sam sposób, w jaki są one wprowadzane: objęte cudzysłowami i wraz z cudzysłowami i innymi zabawnymi znakami poprzedzonymi znakiem ukośnika (\), tak aby w sposób dokładny pokazać zawartość ciągu. Łańcuch objęty jest podwójnym cudzysłowem, jeśli zawiera tylko pojedyncze cudzysłowie, w przeciwnym wypadku objęty jest pojedynczym. (Instrukcja print, które zostanie opisane później, może zostać użyta do wypisywania ciągów znaków bez okalających je cudzysłowów lub znaków cytowania3.1).

Łańcuchy mogą być sklejane za pomocą operatora + i powielane za pomocą *:

>>> slowo = 'Pomoc' + 'A'
>>> slowo
'PomocA'
>>> '<' + slowo*5 + '>'
'<PomocAPomocAPomocAPomocAPomocA>'

Dwa literały napisu występujące jeden obok drugiego są automatycznie sklejane; np. pierwszy wiersz w przykładzie powyżej mógłby być równie dobrze zapisany jako "slowo='Pomoc' 'A'" -- działa to tylko z dwoma literałami, a nie z dowolnym wyrażeniem typu znakowego:

>>> import string # znaczenie słowa 'import' zostanie wyjaśnione później ...
>>> 'str' 'ing'                   #  <-  Tak jest w porządalu
'string'
>>> string.strip('str') + 'ing'   #  <-  to też
'string'
>>> string.strip('str') 'ing'     #  <-  to nie zadziała!
  File "<stdin>", line 1
    string.strip('str') 'ing'
                            ^
SyntaxError: invalid syntax
(SyntaxError: zła składnia)

Łańcuchy znaków mogą być indeksowane. Podobnie jak w C, pierwszy znak w ciągu ma indeks (numer porządkowy) 0. Nie istnieje osobny typ oznaczający znak -- znak jest po prostu napisem o długości jeden. Podobnie jak w języku Icon3.2podciągi znaków mogą zostać wyspecyfikowane za pomocą notacji tzw. wykrawania: dwóch indeksów przedzielonych dwukropkiem.

>>> slowo[5]
'A'
>>> slowo[0:2]
'Po'
>>> word[2:5]
'moc'

Odmiennie niż w C, łańcuchy znaków w Pythonie nie mogą być modyfikowane. Przypisanie do zaindeksowanej pozycji w ciągu powoduje powstanie błędu:

>>> slowo[0] = 'x'
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> slowo[:-1] = 'Splat'
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support slice assignment
(TypeError: na obiekcie nie można wykonać operacji przypisania do elementu)

(TypeError: na obiekcie nie można wykonać opercji przypisania do wycinka)

Stworzenie, jednakże nowego ciągu znaków z połączenia innych jest łatwe i wydajne:

>>> 'x' + słowo[1:]
'xomocA'
>>> 'Splat' + slowo[-1:]
'SplatA'

Indeksy wykrawania posiadają użyteczne parametry domyślne: pominięty pierwszy indeks posiada domyślną wartość zero, a pominięty drugi domyślnie równy jest długości łańcucha znaków, którego dotyczy wykrawanie.

>>> slowo[:2]    # Dwa pierwsze znaki
'Po'
>>> slowo[2:]    # Wszystkie oprócz dwóch pierwszych znaków
'mocA'

Oto użyteczny niezmiennik operacji wykrawania: s[:i] + s[i:] jest równe s.

>>> slowo[:2] + slowo[2:]
'PomocA'
>>> slowo[:3] + slowo[3:]
'PomocA'

Zdegenerowane indeksy wykrawania obsługiwane są dość ostrożnie: indeks, który jest zbyt duży, zastępowany jest długością łańcucha, a ograniczenie górne, które okaże się mniejsze od ograniczenia dolnego, powoduje powstanie pustego napisu.

>>> slowo[1:100]
'omocA'
>>> slowo[10:]
''
>>> slowo[2:1]
''

Aby wyznaczyć znaki, licząc od strony prawej łańcucha znaków, używa się indeksów będących liczbami ujemnymi . Oto przykład:

>>> slowo[-1]     # Ostatni znak
'A'
>>> slowo[-2]     # Przedostatni znak
'c'
>>> slowo[-2:]    # Dwa ostatnie znaki
'cA'
>>> slowo[:-2]    # Wszystkie, oprócz dwóch ostatnich znaków
'Pomo'

Proszę zauważyć, że oznacza to samo co , tak więc nie oznacza liczenia od prawej!

>>> slowo[-0]     # (ponieważ -0 jest równe 0)
'P'

Ujemne wykrojenia, które są przekraczają ograniczenia łańcucha są skracane, ale nie próbuj tego na indeksach jednoelementowych (nie oznaczających wykrawania):

>>> slowo[-100:]
'PomocA'
>>> word[-10]    # błąd
Traceback (innermost last):
  File "<stdin>", line 1
IndexError: string index out of range
(IndexError: indeks napisu poza jego granicami)

Najlepszą formą zapamiętania sposobu działania wykrawania jest wyobrażenie sobie indeksów jako wskazówek odnoszących się do miejsc pomiędzy znakami, gdzie lewa krawędź pierwszego znaku nosi numer 0. Tak więc, prawa krawędź ostatniego znaku w łańcuchu n znaków posiada indeks n, np.:

 +---+---+---+---+---+---+
 | P | o | m | o | c | A |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
 -6  -5  -4  -3  -2  -1

W pierwszym rzędzie liczb możemy zobaczyć pozycje wyznaczone przez indeksy 0...6. Drugi rząd zawiera odpowiednie indeksy ujemne. Wycinek od i do j składa się ze wszystkich znaków pomiędzy krawędziami oznaczonymi odpowiednio i i j.

Długość wycinka można obliczyć z róznicy nieujemnych indeksów, pod warunkiem, że oba mieszczą się w granicach ciągu, np. długość slowo[1:3] równa jest 2.

Wbudowana w interpreter funkcja len() zwraca długość łańcucha:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

 
3.1.3 Napisy Unicode

Od wersji 1.6 wprowadzono nowy typ danych: łańcuchy znaków Unicode. Mogą one zostać użyte do przechowywania i manipulacji danymi typu Unicode (zobacz http://www.unicode.org). Zostały one w niezły sposób zintegrowane z istniejącym w Pythonie systemem napisów i dostarczają niezbędnych konwersji tam, gdzie trzeba.

Unicode posiada przewagę w oznaczeniu każdego znaku używanego w starożytnych i nowoczesnych systemach piśmienniczych. Wcześniejsze rozwiązania umożliwiają przechowywanie tylko 256 znaków, których pozycje w tym zestawie zdefiniowane były przez strony kodowe. Prowadzi to do dużego zamieszania, zwłaszcza w odniesieniu do internalizacji oprogramowania (zwykle nazywa się to "i18n"-- "i" + 18 znaków + "n" = internalization). Unicode rozwiązuje te problemy poprzez zdefiniowanie jednej strony kodowej dla wszystkich systemów piśmienniczych.

Stworzenie łańcucha znaków Unicode w Pythonie jest tak samo proste jak w przypadku zwykłego:

>>> u'Hello World !'
u'Hello World !'

Mała litera "u" z przodu łańcucha oznacza, że zostanie stworzony łańcuch Unicode. Jeśli chce się umieścić jakieś znaki specjalne w tym łańcuchu, można zrobić to poprzez kodowanie Unicode-Escape. Poniższy przykład pokazuje jak to uczynić:

>>> u'Hello\\u0020World !'
u'Hello World !'

Sekwencja cytowania (ang. escape sequence) \\u0020 oznacza wstawienie znaku Unicode na podanej pozycji z kodem określonym szesnastkowo 0x0020 (znak spacji).

Inne znaki interpretowane są poprzez użycie ich odpowiedniego numeru porządkowego wprost jako porządku wyrażonego w Unicode. Fakt, iż pierwsze 256 znaków Unicode są takie same jak standardowego zestawu Latin-1 używanego w wielu krajach zachodnich, proces kodowania ich w Unicode bardzo się upraszcza.

Kąsek dla ekspertów: istnieje także tryb ,,surowy'' wprowadzania znaków, podobnie jak dla zwykłych łańcuchów. Trzeba dołączyć z przodu łańcucha znak 'r', aby Python traktował wszystko w tym łańcuchu jako znaki kodowane w trybie Raw-Unicode-Escape. Będzie się to stosowało tylko do konwersji \\uXXXX, tak jak w przykładzie powyżej, gdy pojawia się nieparzysta liczba ukośników z przodu litery 'u'.

>>> ur'Hello\u0020World !'
u'Hello World !'
>>> ur'Hello\\u0020World !'
u'Hello\\\\u0020World !'

Tryb surowy jest najbardziej użyteczny w przypadku, gdy trzeba wprowadzić mnóstwo ukośników, np. jakieś wyrażenie regularne.3.3

Oprócz wspomnianych przed chwilą standardowych sposobów kodowania znaków, Python dostarcza wiele innych sposobów tworzenia łańcuchów Unicode opartych na znanych już kodowaniach.

Funkcja wbudowana unicode() dostarcza środków dostępu do wszystkich zarejestrowanych kodeków Unicode (tzw. COders i DECoders). Niektóre z bardziej znanych kodowań, dla których istniejące kodeki mogą przeprowadzić konwersje to Latin-1, ASCII, UTF-8 i UTF-16. Dwa ostatnie są systemami kodowania zmiennej długości, które pozwalają przechowywać znaki Unicode w 8 lub 16 bitach. Python używa UTF-8 jako domyślnego kodowania. Staje się to ważne, gdy decydujemy się umieszczać takie znaki w plikach lub drukować.

>>> u"äöü"
u'\344\366\374'
>>> str(u"äöü")
'\303\244\303\266\303\274'

Jeśli przechowujesz dane kodowane w specyficzny sposób i chce się wyprodukować odpowiadający im łańcuch Unicode, można użyć unicode() z podaną nazwą kodowania jako drugi parametr wywołania.

>>> unicode('\303\244\303\266\303\274','UTF-8')
u'\344\366\374'

Metoda łańcucha znakowego encode() pozwala dokonać odwrotnej konwersji.

>>> u"äöü".encode('UTF-8')
'\303\244\303\266\303\274'

 
3.1.4 Listy

Istnieje w Pythonie pewna liczba złożonych typów danych, używanych do grupowania innych wartości. Najbardziej użytecznym typem jest lista, którą można zapisać jako listę elementów poprzedzielanych przecinkiem, umieszczoną w kwadratowych nawiasach. Elementy listy nie muszą być tego samego typu.3.4

>>> a = ['wędzonka', 'jaja', 100, 1234]
>>> a
['wędzonka', 'jaja', 100, 1234]

Podobnie jak indeksy łańcuchów znaków, indeksy listy rozpoczynają się od wartości 0. Listy mogą być przedmiotem operacji wykrawania, sklejania itd.:

>>> a[0]
'wędzonka'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['jaja', 100]
>>> a[:2] + ['bekon', 2*2]
['wędzonka', 'jaja', 'bekon', 4]
>>> 3*a[:3] + ['Srutututu!']
['wędzonka', 'jaja', 100, 'wędzonka', 'jaja', 100, 'wędzonka', 'jaja', 100,
'Srutututu!']

Odmiennie niż napisy, które są niemutowalne, można zmieniać poszczególne elementy listy:

>>> a
['wędzonka', 'jaja', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['wędzonka', 'jaja', 123, 1234]

Możliwe jest także przypisanie do wycinka, co może także zmienić długość listy:

>>> # Zastąp pewne elementy:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Inne usuń:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Włóż parę:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> a[:0] = a     # Wstaw kopię siebie na początek
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]

Wbudowana funkcja len() również dotyczy list:

>>> len(a)
8

Możliwe jest zagnieżdżanie list (tworzenie list, której elementami są inne listy), np:

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')     # Zobacz podpunkt 5.1
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']

Zauważcie, że w ostatnim przykładzie p[1] i q tak naprawdę odnoszą się do tego samego egzemplarza obiektu! Powrócimy do obiektowej semantyki później.

 
3.2 Pierwsze kroki w programowaniu

Dodawanie 2 do 2 jest oczywiście nie wszystkim, co można zrobić w Pythonie. Możemy na przykład napisać początkowe elementy ciągu Fibonacciego: 3.5

>>> # Ciąg Fibonacciego:
... # suma dwóch elementów definiuje następny element
... a, b = 0, 1
>>> while b < 10:
...       print b
...       a, b = b, a+b
...
1
1
2
3
5
8

Powyższy przykład ukazuje nam parę nowych cech Pythona.



... cytowania3.1
Czyli znaków specjalnych poprzedzonych znakiem ukośnika
... Icon3.2
...pierwszy raz słyszę o takim języku
... regularne.3.3
Moduł "re" do obsługi wyrażeń regularnych opisany został w «Opisie biblioteki»
... typu.3.4
I to jest to, co najbardziej rajcuje tygryski...
...Fibonacciego: 3.5
Kiedy się wreszcie skończy katowanie Fibbonaciego?!
Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.