Previous Page

Up One Level

Next Page

Python Tutorial

Contents

Index

Vorige: 2. Using the Python Omhoog: Python Tutorial Volgende: 4. Meer over control flow
Onderdelen
  • 3.1 Python als rekenmachine gebruiken
    • 3.1.1 Getallen
    • 3.1.2 Strings
    • 3.1.3 Unicodestrings
    • 3.1.4 Lists
  • 3.2 De eerste stappen op het programmeerpad


3. Een informele inleiding in Python

In de volgende voorbeelden worden invoer en uitvoer van elkaar onderscheiden door de aan- of afwezigheid van prompts (">>> " en "... "): om het voorbeeld na te spelen, moet je alles na de voorbeeldprompt overtypen op de prompt. Regels die niet met een prompt beginnen, zijn uitvoer van de interpreter. Merk op dat regel met alleen een secundaire prompt betekent dat je een blanco regel moet invoeren; hiermee wordt een commando dat meerdere regels omspant, afgesloten.

Veel van de voorbeelden in deze tutorial (ook voorbeelden die op de interactieve prompt worden ingevoerd) bevatten commentaar. In Python begint commentaar met een hekje, "#", en duurt tot het einde van de fysieke regel. Commentaar mag voorkomen aan het begin van een regel, of volgend op whitespace of code, maar niet binnen een string literal. Een hekje binnen een string literal is gewoon een hekje.

Enkele voorbeelden:

# dit is de eerste commentaarregel
SPAM = 1                 # en dit is het tweede commentaar 
                         # ... en nog een derde!
STRING = "# Dit is geen commentaar."


3.1 Python als rekenmachine gebruiken

Laten we nu wat simpele Python-commando's uitproberen. Start de interpreter op en wacht tot de primaire prompt, ">>> " verschijnt. (Dit zou niet lang moeten duren.)


3.1.1 Getallen

De interpreter gedraagt zich als een eenvoudige rekenmachine: als je een expressie intypt, drukt hij de waarde af. De syntax van de expressies is rechttoe-rechtaan: de operators +, -, * en / werken hetzelfde als in de meeste andere talen (bijvoorbeeld Pascal of C), en je kunt haakjes gebruiken om expressies te groeperen. Bijvoorbeeld:

>>> 2+2
4
>>> # Dit is commentaar  
... 2+2
4
>>> 2+2  # en commentaar op dezelfde regels als de code
4
>>> (50-5*6)/4
5
>>> # Integer-deling rondt af naar beneden:
... 7/3
2
>>> 7/-3
-3

Net als in C, wordt het “is gelijk”-teken ("=") gebruikt om een waarde toe te kennen aan een variabele. Het resultaat van een toekenning wordt niet afgedrukt:

>>> breedte = 20
>>> hoogte = 5*9
>>> breedte * hoogte
900

Een waarde kan tegelijkertijd aan meerdere variabelen worden toegekend:

>>> x = y = z = 0  # x, y en z zijn nul
>>> x
0
>>> y
0
>>> z
0

Floating point (“drijvende komma”) operaties worden volledig ondersteund; operators met operands van verschillende types converteren de integer naar floating point:

>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5

Complexe getallen worden eveneens ondersteund; imaginaire getallen worden geschreven met een achtervoegsel "j" of "J". Complexe getallen waarvan de reële component ongelijk is aan nul, worden geschreven als "(real+imagj)", of kunnen aangemaakt worden met de functie "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)

Complexe getallen worden altijd weergegeven als twee floating point getallen, die het reële en het imaginaire deel vertegenwoordigen. Om deze delen af te leiden uit een complex getal z, kun je z.real en z.imag gebruiken.

>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5

De conversiefuncties naar floating point en integer (float(), int() and long()) werken niet voor complexe getallen – er is meer dan één correcte manier om een complex getal te converteren naar een reëel getal. Gebruik abs(z) om zijn absolute waarde te verkrijgen (als een float) of z.real om het reële gedeelte te verkrijgen.

>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
5.0
>>>

In interactieve modus wordt de laatst afgedrukte expressie toegekend aan de variabele _. Dat betekent dat het, wanneer je Python als rekenmachine gebruikt, vrij eenvoudig is om op berekeningen voort te bouwen:

>>> belasting = 12.5 / 100
>>> prijs = 100.50
>>> prijs * belasting
12.5625
>>> prijs + _
113.0625
>>> round(_, 2)
113.06
>>>

Deze variabele moet door de gebruiker als read-only behandeld worden. Door er expliciet een waarde aan toe te kennen, creëer je een aparte lokale variabele met dezelfde naam, waardoor de ingebouwde variabele en zijn magische werking afgeschermd worden.


3.1.2 Strings

Behalve getallen kan Python ook strings manipuleren. Strings kunnen op verschillende manieren worden weergegeven. Ze kunnen in enkele of dubbele aanhalingstekens worden ingesloten:

>>> 'spam eggs'
'spam eggs'
>>> 'Monty\'s'
"Monty's"
>>> "Monty's"
"Monty's"
>>> '"Ja," zei hij.'
'"Ja," zei hij.'
>>> "\"Ja,\" zei hij."
'"Ja," zei hij.'

String literals kunnen meerdere regels omspannen; hier zijn verschillende methoden voor. Je kunt gebruikmaken van vervolgregels, door een backslash (\) als laatste karakter op de regel op te nemen ten teken dat de volgende regel logisch gezien het vervolg van deze regel is:

hallo = "Dit is een vrij lange string die verschillende regels\n\
tekst bevat, net als je dat in C zou doen.\n\
    Merk op dat whitespace aan het begin van de regel \
 betekenis heeft."

print hallo

Merk op dat newline-karakters nog steeds als \n in de string opgenomen moeten worden; newline-karakters na de afsluitende backslash worden genegeerd. De uitvoer van dit voorbeeld ziet er als volgt uit:

Dit is een vrij lange string die verschillende regels
tekst bevat, net als je dat in C zou doen.
    Merk op dat whitespace aan het begin van de regel betekenis heeft.

Als we echter van de string literal een “raw” string maken, worden de \n characters als aanduidingen voor een nieuwe regel geïnterpreteerd; zowel de backslash aan het eind van de regel als het newline-karakter in de broncode worden als data in de string opgenomen. Het voorbeeld:

hallo = r"Dit is een vrij lange string die verschillende regels\n\
tekst bevat, net als je dat in C zou doen."

print hello

geeft dus als uitvoer:

Dit is een vrij lange string die verschillende regels\n\
tekst bevat, net als je dat in C zou doen.

Verder kunnen strings in een paar driedubbele aanhalingstekens van hetzelfde type vervat worden: """ of '''. Bij het gebruik van driedubbele aanhalingstekens hoeven regeleindes niet ge-escaped te worden; deze zullen als onderdeel van de string worden gezien.

print """
Usage: dinges [OPTIES] 
     -h                        Toont deze gebruiksaanwijzing
     -H hostnaam               Naam van de host waarmee verbinding moet worden gelegd
"""

produceert de volgende uitvoer:

Usage: dinges [OPTIES] 
     -h                        Toont deze gebruiksaanwijzing
     -H hostnaam               Naam van de host waarmee verbinding moet worden gelegd

De interpreter drukt het resultaat van stringoperaties af zoals ze ingevoerd werden: tussen aanhalingstekens, en met aanhalingstekens en andere vreemde characters ge-escaped met backslashes; zo wordt dus de exacte waarde van de string getoond. Als de string wel enkele maar geen dubbele aanhalingstekens bevat, wordt hij ingesloten in dubbele aanhalingstekens; anders in enkele. (Om strings zonder aanhalingstekens of escapes te schrijven, kun je het print-statement, wat later uitgelegd wordt, gebruiken.)

Strings kunnen worden geconcateneerd (aan elkaar geplakt) met de + operator. Met * kunnen ze herhaald worden:

>>> woord = 'Help' + 'A'
>>> woord
'HelpA'
>>> '<' + woord*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'

Twee string literals naast elkaar worden automatisch geconcateneerd; de eerste regel hierboven had dus ook als "woord = 'Help' 'A'" geschreven kunnen worden. Dit werkt alleen met twee literals, en niet met willekeurige stringexpressies:

>>> 'str' 'ing'                   #  <-  Dit is goed
'string'
>>> 'str'.strip() + 'ing'   #  <-  Dit is goed
'string'
>>> 'str'.strip() 'ing'     #  <-  Dit is fout
  File "<stdin>", line 1, in ?
    'str'.strip() 'ing'
                      ^
SyntaxError: invalid syntax

Strings kunnen van een index voorzien worden; net als in C, heeft het eerste karakter van een string de index 0. Er is geen apart type voor char (karakters); een karakter is gewoon een string met lengte 1. Net als in Icon, kunnen substrings gespecificeerd worden met de slice-notatie: two indices die door een dubbele punt van elkaar gescheiden worden.

>>> woord[4]
'A'
>>> woord[0:2]
'He'
>>> woord[2:4]
'lp'

De standaardwaarden voor slice indices hebben een paar nuttige standaardwaarden; de standaardwaarde van een weggelaten eerste index is nul, die van de tweede index is de lengte van de string die gesliced wordt.

>>> woord[:2]    # De eerste twee karakters
'He'
>>> woord[2:]    # Alles, behalve de eerste twee karakters
'lpA'

Anders dan in C, kunnen strings in Python niet gewijzigd worden: een assignment (“toekenning”) aan een geïndexeerde positie in een string levert een foutmelding op:

>>> woord[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> woord[:1] = 'Splat'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support slice assignment

Het creëren van een nieuwe string op basis van gecombineerde inhoud is weer wel eenvoudig en efficiënt:

>>> 'x' + woord[1:]
'xelpA'
>>> 'Splat' + woord[4]
'SplatA'

Een nuttige eigenschap van slice-operaties is het volgende: s[:i] + s[i:] is gelijk aan s.

>>> woord[:2] + woord[2:]
'HelpA'
>>> woord[:3] + woord[3:]
'HelpA'

Onvolledige slice indices worden elegant afgevangen: te grote indices worden vervangen door de lengte van de string, en bij een bovengrens die kleiner is dan de ondergrens, wordt een lege string teruggegeven.

>>> woord[1:100]
'elpA'
>>> woord[10:]
''
>>> woord[2:1]
''

Om de indices van rechts naar links te tellen in plaats van van links naar rechts, kunnen negatieve getallen gebruikt worden. Bijvoorbeeld:

>>> woord[-1]     # Het laatste karakter
'A'
>>> woord[-2]     # Het op-één-na laatste karakter
'p'
>>> woord[-2:]    # De laatste twee karakters
'pA'
>>> woord[:-2]    # De hele string, op de laatste twee karakters na
'Hel'

Let op: -0 is hetzelfde als 0, dus deze begint niet aan de rechterkant te tellen!

>>> woord[-0]     # (want -0 is gelijk aan 0)
'H'

Negatieve slice indices die out-of-range zijn, worden afgekapt, dit werkt niet voor enkelvoudige (niet-slice) indices:

>>> woord[-100:]
'HelpA'
>>> woord[-10]    # error
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: string index out of range

De beste manier om te onthouden hoe slices werken, is om je de indices voor te stellen als pointers tussen karakters, waarbij de linkerrand van het eerste karakter 0 is genummerd. De rechterrand van het laatste karakter van een string van n karakter s heeft dan index n, bijvoorbeeld:

 +---+---+---+---+---+ 
 | H | e | l | p | A |
 +---+---+---+---+---+ 
 0   1   2   3   4   5 
-5  -4  -3  -2  -1

De eerste rij getallen duidt de positie van de indices 0 tot en met 5 in de string aan; de tweede rij duidt de corresponderende negatieve indices aan. De slice van i tot j bestaat uit alle karakters tussen de randen die i resp. j heten.

Voor niet-negatieve indices is de lengte van een slice gelijk aan het verschil van de indices, als beide onbegrensd zijn. Bijvoorbeeld: de lengte van woord[1:3] is 2.

De ingebouwde functie len() geeft de lengte van de string terug:

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

Zie ook:

Sequencetypes
Strings, evenals de Unicodestrings die in de volgende paragraaf beschreven worden, zijn voorbeelden van sequencetypes, en ondersteunen de voor dergelijke types gebruikelijke operaties.
Stringmethods
Zowel strings als Unicodestrings ondersteunen een groot aantal methods voor elementaire transformaties en zoekfunctionaliteit.
Stringopmaak-operaties
Hier worden de opmaakoperaties beschreven die aangeroepen worden wanneer strings en Unicodestrings fungeren als de linkeroperand van de % operator.


3.1.3 Unicodestrings

Sinds Python 2.0 heeft de programmeur een nieuw datatype voor tekstopslag tot zijn beschikking: het Unicodeobject. Dit kan gebruikt worden om Unicode-data op te slaan en te bewerken (see http://www.unicode.org/), en is goed geïntegreerd met de bestaande stringobjecten; daar waar nodig, wordt gezorgd voor automatische conversie.

Unicode heeft het voordeel dat het voor ieder karakter in ieder schrift dat gebruikt wordt in moderne en antieke teksten, één getal beschikbaar heeft. Voorheen waren er slechts 256 getallen mogelijk voor schrifttekens; teksten waren normaal gesproken gebonden aan een code page waarin de getallen gemapt werden naar schrifttekens. Dit leidde tot grote verwarring, vooral voor wat betreft internationalisatie (“internationalization”, meestal geschreven als "i18n": "i" + het aantal letters van het woord “internationalization” + "n") van software. Unicode lost deze problemen op door één code page te definiëren voor alle schriften.

Het maken van een Unicodestring is in Python net zo simpel als het maken van een gewone string:

>>> u'Hallo Wereld !'
u'Hallo Wereld !'

De kleine "u" voor het eerste aanhalingsteken geeft aan dat het de bedoeling is om een Unicodestring te maken. Als je speciale karakters wilt opnemen in de string, kan dat met behulp van de Python Unicode-Escape encoding. Het volgende voorbeeld laat zien, hoe:

>>> u'Hallo\u0020Wereld !'
u'Hallo Wereld !'

De escape sequence \u0020 geeft aan dat het Unicodekarakter met getalswaarde 0x0020 (een spatie) ingevoegd moet worden.

Van andere karakters worden de getalswaarden rechtstreeks als Unicodegetallen geïnterpreteerd. Voor het gebruik van string literals die Latin-1 encoded zijn (zoals gebruikelijk in veel westerse landen), komt het erg goed uit dat de eerste 256 Unicodekarakters hetzelfde zijn als de 256 Latin-1 karakters.

Voor gevorderde programmeurs is er ook voor Unicode een “raw” module, net als voor gewone strings. Om Python de Raw-Unicode-Escape encoding te laten gebruiken, zet je 'ur' voor de eerste quote van de string. De hierboven genoemde \uXXXX-conversie wordt alleen toegepast als de kleine 'u' voorafgegaan wordt door een oneven aantal backslashes.

>>> ur'Hallo\u0020Wereld !'
u'Hallo Wereld !'
>>> ur'Hallo\\u0020Wereld !'
u'Hallo\\\\u0020Wereld !'

De raw modus komt vooral van pas als je veel backslashes moet invoeren, wat bijvoorbeeld nodig kan zijn bij regular expressions.

Naast deze standaardencodings biedt Python nog een aantal andere mogelijkheden voor het creëren van Unicodestrings op basis van een bekende encoding.

De ingebouwde functie unicode() biedt toegang tot alle geregistreerde Unicode codecs (COders en DECoders). Enkele bekendere encodings die met behulp van deze codecs geconverteerd kunnen worden, zijn Latin-1, ASCII, UTF-8, en UTF-16. Bij de laatste twee encodings kan een Unicodekarakter in één of meer bytes opgeslagen worden. De standaardencoding is meestal ASCII; ASCII laat karakters in het bereik van 0 tot 127 door, en wijst alle andere karakters met een foutmelding af. Wanneer een Unicodestring wordt afgedrukt, naar bestand geschreven, of geconverteerd met str(), wordt een conversie uitgevoerd op basis van de standaardencoding.

>>> u"abc"
u'abc'
>>> str(u"abc")
'abc'
>>> u"äöü"
u'\xe4\xf6\xfc'
>>> str(u"äöü")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

Unicode-objecten hebben een method encode() waarmee een Unicodestring geconverteerd kan worden naar een 8-bit string op basis van een specifieke encoding. Deze method wordt met één argument aangeroepen: de naam van de encoding. Gebruik bij voorkeur kleine letters voor namen van encodings.

>>> u"äöü".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'

Als je data met een specifieke encoding hebt, en je wilt deze omzetten naar de corresponderende Unicode-string, dan kun je hiervoor de functie unicode() gebruiken met de naam van de encoding als tweede argument.

>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')
u'\xe4\xf6\xfc'


3.1.4 Lists

Python kent een aantal compound (samengestelde) datatypes, die gebruikt worden om waarden te groeperen. De meest veelzijdige daarvan is de list
(lijst)
, die geschreven wordt als een lijst van waarden (items) tussen vierkante haken, van elkaar gescheiden door komma's. De items in een list hoeven niet allemaal hetzelfde type te hebben.

>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]

Net als stringindices, beginnen listindices bij 0. Lists kunnen, net als strings, worden gesliced, geconcateneerd, enzovoort:

>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boe!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!']

Anders dan strings, die immutable (onveranderlijk) zijn, kunnen individuele elementen van een list wel gewijzigd worden:

>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]

Toekenning aan slices behoort ook tot de mogelijkheden; hierdoor kan zelfs de lengte van de list wijzigen:

>>> # Vervang enkele items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Verwijder enkele itemss:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Voeg er een paar in:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> a[:0] = a     # Voeg (een kopie van) zichzelf in aan het begin
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]

De ingebouwde functie len() kan ook op lists toegepast worden:

>>> len(a)
8

Het is mogelijk om lists te nesten (dus om lists te creëren die lists bevatten); bij voorbeeld:

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

Merk op dat in het laatste voorbeeld p[1] en q eigenlijk naar hetzelfde object verwijzen! Op de semantiek van objecten komen we later terug.


3.2 De eerste stappen op het programmeerpad

Vanzelfsprekend kunnen we ingewikkeldere dingen doen met Python dan twee en twee bij elkaar optellen. We kunnen bijvoorbeeld het begin van de Fibonaccireeks als volgt noteren:

>>> # Fibonacci series:
... # de som van twee elementen definieert het volgende element
... a, b = 0, 1
>>> while b < 10:
...       print b
...       a, b = b, a+b
... 
1
1
2
3
5
8

In dit voorbeeld introduceren we een aantal nieuwe zaken.

  • De eerste regel bevat een multiple assignment (meervoudige toekenning): aan de variabelen a en b worden gelijktijdig de nieuwe waarden 0 en 1 toegekend. Dit gebeurt opnieuw op de laatste regel, waar gedemonstreerd wordt dat de expressies aan de rechterkant eerst allemaal geëvalueerd worden voordat ook maar één van de assignments plaatsvindt. De expressies aan de rechterkant worden van links naar rechts geëvalueerd.

  • De while lus wordt uitgevoerd zolang de conditie (in dit geval: b < 10) waar blijft. Net als in C, is in Python iedere integer ongelijk aan nul waar; nul is onwaar. De conditie kan ook een string of een lijst zijn, of wat voor sequence dan ook; alles met een lengte ongelijk aan nul is waar, lege sequences zijn onwaar. De test uit het voorbeeld is een eenvoudige vergelijking. De standaardvergelijkingsoperators worden hetzelfde geschreven als in C: < (kleiner dan), > (groter dan), == (gelijk aan), <= (kleiner dan of gelijk aan), >= (groter dan of gelijk aan) en != (ongelijk aan).

  • De body van de lus is ingesprongen (indented): inspringing is de manier waarop in Python statements gegroepeerd worden. Python beschikt (nog!) niet over intelligente editing op invoerregelniveau, dus je moet zelf nog een tab of spatie(s) typen voor elke ingesprongen regel. In de praktijk zul je de wat complexere invoer voor Python in een teksteditor voorbereiden; de meeste teksteditors hebben een faciliteit voor automatisch inspringen. Bij het interactief invoeren van een samengesteld statement, moet dit gevolgd worden door een lege regel om aan te geven dat het statement compleet is (aangezien de parser niet kan raden dat je de laatste regel hebt ingetypt). Merk op dat je iedere regel binnen een blok even ver moet laten inspringen.

  • Het print-statement drukt de waarde af van de expressie(s) die eraan meegegeven worden. Dit statement wijkt af van “gewoon de expressie intypen” (zoals we eerder in het voorbeeld van de rekenmachine deden) door hoe het omgaat met meervoudige expressies en strings. Strings wordt afgedrukt zonder quotes, en tussen de items wordt een spatie ingevoegd, zodat je een en ander netjes kunt formatteren:

    >>> i = 256*256
    >>> print 'De waarde van i is', i
    De waarde van i is 65536

    Door een komma achter de expressie toe te voegen, voorkom je dat na de uitvoer naar een nieuwe regel wordt gesprongen:

    >>> a, b = 0, 1
    >>> while b < 1000:
    ...     print b,
    ...     a, b = b, a+b
    ... 
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

    Merk op dat de interpreter een nieuwe regel invoegt voordat de volgende prompt afgedrukt wordt, als de laatste regel onvoltooid gelaten is.


Previous Page

Up One Level

Next Page

Python Tutorial

Contents

Index

Vorige: 2. Using the Python Omhoog: Python Tutorial Volgende: 4. Meer over control flow
Release 2.3.4, documentation updated on May 20, 2004.
See About this document... for information on suggesting changes.