basics michael poeltl © 2011,2013

Erste Schritten

Dein Einstieg

Python ist eine Skriptsprache, eine sogenannte interpretierte Sprache, was bedeutet, dass wir den von uns geschriebenen Programmcode nicht selber in Maschinensprache (binaercode) mithilfe eines Compilers übersetzen lassen müssen (wie es, z.B., bei den Programmiersprachen Fortran, C oder D der Fall ist, die zu den sogenannten Hochsprachen zählen).

Ein (auch von uns verfasstes) Pythonprogramm nennt man Python-script, und wir fügen dem Namen des python-script-files die Endung .py an.

Zum Beispiel, 'mein_erstes.py', oder 'fancystuff.py'

Die offizielle website python's ist www.python.org.
Um die offizielle Dokumentation über python-3.3 aufzurufen, klicke diesen link. Wird schwer sein, diesen link auf die aktuelle Version von python-3.X zu halten. Du findest dann später die docu zur aktuellen Version sicher auch selber.

Installiere dir python3.
Nutze dazu ein Paket, das dir von Deiner distro angeboten wird oder installiere von source.

Und schließlich kommt es zum ersten Aufruf des python-Interpreters auf der Kommandozeile (bei mir bash).

?> python3
Python 3.3.2 (default, May 16 2013, 09:53:09) 
[GCC 4.4.5] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Ich tippte python3, da ich auch python2.6.5 und python2.7.4 installiert habe. Mit python3 ist es klar, dass ich python3.3 meinte (sollte noch python3.2 im Text auftauchen, dann deshalb, weil ich davor python3.2 verwendet hatte - ich werde nicht alle python3.2 austauschen auf die aktuelle Version. Code-Beispiele funktionieren in python3.3 gleich wie in python3.2!).
Ich arbeite also auf meiner Ubuntu-10.04-notebook (Stand vom April 2011) mit python-3.2. Das kann sich freilich ändern, wenn neuere stable-releases im Laufe meiner Schreiberei verfügbar sind.

Man schreibt python-code natürlich in files (python-scripts), kann aber den python-Interpreter direkt aufrufen, und interaktiv python-syntax ausprobieren.
Und rechtzeitig mit python3.3 kam ipython3 heraus (check die aktuelle Version von ipython) - die interaktive python-commandline.
Um den python-Interpreter wieder verlassen zu können, drücke strg+d. Es geht auch exit() und quit() oder (the geeky way)

>>> raise SystemExit
user@host:~>

python-code kann man sogar direkt auf der command-line tippseln. Befehlszeilen werden durch Strichpunkt voneinander getrennt).

?> python3 -c 'print ("Hello World!"); print ("python is great!")'
Hello World!
python is great!

?>

Der python-Interpreter könnte noch folgendermaßen aufgerufen werden.

user@linux:~> /usr/bin/env python3
...
>>> credits
    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more 
information.
>>> print ('hello, world!')
hello, world!
>>>

quoting first!
strings in python müssen in einfache oder doppelte Anführungszeichen eingeschlossen werden.
So, print(hello,world!) würde in einem syntax error enden.

>>>  print(hello,world!)                                              
  File "<stdin>", line 1                                             
    print(hello,world!)                                              
                     ^                                               
SyntaxError: invalid syntax                                          
>>>

in python hast Du es von Anfang an mit Objekten zu tun.

>>> print (5)
5
>>> print ('a')
a
>>>

Hier der zweite Kontakt mit der print-Funktion print() (wir werden an anderer Stelle genau erläutern, was eine Funktion ist).
Im obigen Beispiel haben wir zuerst ein int-Objekt ausgeben lassen, danach ein string-Objekt.

Das waren die ersten Objekt-Typen: int(eger) und str(ings)
(beides built-in-[abstract]-datatypes)

Ein Objekt hat

(das werde ich wahrscheinlich öfter aufschreiben, mich also wiederholen; bei den wichtigen Infos ist das sinnvoll (sonst versuche ich Wiederholungen zu vermeiden).
Daten bzw. datastructures werden durch solche Objekte repräsentiert. 5 und '5' sind zwei Objekte unterschiedlichen Typs! Daran muss man sich erst einmal gewöhnen.

ein erstes python-script, test.py (abschreiben, copy-paste oder aus der Beispielsammlung holen)

user@linux:~> vim ./bsp/basics/test.py
#! /usr/bin/env python3

#  die Zeilen, die mit # beginnen (ausser der obersten) nennt man
#+ einen Kommentar.
#+ Kommentare werden vom Interpreter nicht interpretiert

print(credits)

# Ende vom Skript
user@linux:~> chmod +x ./bsp/basics/test.py
user@linux:~> ./bsp/basics/test.py
    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more     
information.
user@linux:~>

chmod +x war notwendig, um das Skript ausführbar zu machen.
#! ist die sogenannte sha bang (sha -> sharp (hash, Raute, Kreuzgitter), bang -> Ausdruck in der Programmiererei für das Rufzeichen), der dann der Pfad hin zum Interpreter folgen soll, für den die Programmzeilen mit der ihm eigenen Syntax gedacht sind.

#! /bin/bash

würde die bash als Interpreter heranziehen - damit diese Zeile ausgeführt wird, brauchen wir eben das gesetzte x-Recht.
Das Skript ließe sich auch noch folgendermaßen ausführen (aufrufen ohne x-Recht):

user@linux:~> python3 ./bsp/basics/test.py
    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information.
user@linux:~>

dann allerdings wird die sha bang (#!) vom Interpreter als Kommentar der Programmiererin gedeutet und als nicht zu interpretieren übergangen.

Typ-Abfrage

Sehr praktisch, wenn man wissen muss, welchen Typs ein Objekt ist.

>>> a = 5
>>> type(a)
<class 'int'>
>>> isinstance(a, int) #zeigt a auf eine Instanz der Klasse int?
True
>>> #ja (True), a zeigt auf ein integer-Objekt
>>> type(str())()
''
>>>

id-Abfrage

mit Hilfe der built-in-function id() lässt sich diese einmalig vorkommende object-id abfragen.

>>> id(a)
137068896
>>> id(5)
137068896
>>>

In einem python-script funktionieren die Ausgaben aber nicht so ohne weiteres; hier nutzen wir den python-Interpreter interaktiv und können uns das print() sparen; - in python-scripts (in files gegossener python-code) musst die print-Funktion print() immer aufrufen, um eine Ausgabe zu produzieren.

>>> print (type(a))
<class 'int'>
>>> print (id(a))
137068896
>>>

Die Objekte kugeln also im Hauptspeicher an bestimmteh Speicheradressen herum -
um sie ansprechen zu können, benötigen wir Namen, die auf diese Objekte zeigen
Die Namen werden treffend identifier oder Referenz genannt.
Die Namen referenzieren oder zeigen auf das Objekt - wir erreichen die Objekte über die Namen, die auf diese Objekte zeigen.
Wir kennen die Namen auch unter der Bezeichnung Variable (Plazthalter), was es aber nicht so ganz richtig trifft. identifier, reference oder einfach nur name sind am gängigsten.

über Namen

Ein Name zeigt immer auf ein Objekt, niemals auf einen anderen Namen!
Namen dürfen kein keyword (wie z.B. for --> reservierte Wörter) sein (bekommst eh eine diesbezügliche Fehlermeldung - und ich schreib dir die Liste der reservierten keywords (halt den aktuellen Stand, der sich auch wieder ändern kann) an anderer Stelle gesondert auf. Bringt wenig, wenn ich dir's jetzt aufliste).

Namen dürfen nicht mit einer Zahl beginnen und keine Sonderzeichen beinhalten. Sie dürfen mit Unterstrich beginnen, enden oder Unterstrich beinhalten.
und wenn Du einmal einen unerlaubten Namen verwenden solltest, dann spuckt Dir der Interpreter eh eine Fehlermeldung (Exception) aus. Im Namen dürften seit python3 aber, zum Beispiel, deutsche Umlaute vorkommen, weil ja das default-encoding utf-8 ist, nur, ich würde jeder davon dringend abraten. Schreib' weiterhin anstelle von ä ein ae, oder besser, nutze englische Bezeichnungen (obwohl ich bei meinen sample-scripts hier alles eingedeutscht habe - im Regelfall nutze ich nur englische Namen für meine identifier).

>>> a = c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>>

Die Namen werden in einem namespace abgelegt. c gibt es noch nicht im namespace, daher der NameError.
a könnte nämlich auf dasselbe Objekt zeigen, auf das c zeigt. Dann würden beide Namen auf dasselbe 'eine' Objekt im Arbeitsspeicher zeigen (und NICHT Name a auf Name c)

>>> c = 'kuckuck'
>>> a = c
>>> print (id(a))
3077457696
>>> print (id(c))
3077457696
>>>

Den namespace kannst mittels der dir()-Funktion einsehen.

>>> print (dir())
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'c']
>>>

Hilfe zu dir() könntest Du Dir ansichtig machen mittels

>>> help(dir)
Help on built-in function dir in module builtins:

dir(...)
    dir([object]) -> list of strings
...

dir() id() type() sind built-in Funktionen.
Da gibt es noch eine ganze Menge davon - lernen wir peu-en-peu kennen.
Vorsicht: wenn der Name der built-in-function KEIN keyword ist, dann kannst/darfst Du den Namen der built-in-function verwenden - der Name von id steht in dir(__builtins__).

Note: Wenn die Anweisung mit einem Leerzeichen beginnen würde, endete das mit einer Fehlermeldung. Wir werden später noch näher auf Syntaxfragen eingehen. Für den Anfang merken wir uns, dass Anweisungen nicht mit einem Leerzeichen beginnen dürfen.

>>>  'id' in dir(__builtins__)
  File "<stdin>", line 1
    'id' in dir(__builtins__)
    ^
IndentationError: unexpected indent
>>>

Krachbumm wegen Leerzeichen am Anfang

>>> 'id' in dir(__builtins__)
True
>>>

dir() listet uns die Namen im namespace auf.
Wenn Du id in den namespace schreibst (Name id zeigt auf ein Objekt), dann wird der Name im Hauptnamensraum genommen und der (intern-automatisierte) Weg zu builtins nimmer beschritten, weil ja schon ein Name 'id' gefunden wurde.

>>> id = 8
>>> print( id(a) )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>>

Du musst das von Dir eingetragene id wieder aus den namespace '__main__' (Hauptnamensraum) entfernen (Namen löschen), damit wieder auf den Namen id in __builtins__ zurückgegriffen werden kann.

>>> del id
>>> print (id(a))
3077457696
>>>

geschafft. Nix passiert!
aber nicht:

>>> id(1)
136012640
>>> del __builtins__.id
>>> id(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'id' is not defined
>>>

das hat einmal ein Schüler fabriziert und gleich drauf gemeint, dass er keine built-in-function id() hätte ;-)
keywords sind Namen, die für python wichtig sind. Ohne die keywords lassen sich keine python-Anweisungen schreiben. Daher hat man keywords derart geschützt, dass man diese Namen NICHT auf ein anderes Objekt umlenken kann und diese auch nicht aus dem namespace entfernen kann. Aber vielleicht geht das sogar, nur halt auf komplizierten Umwegen!? Nur, wer will das schon?

Fehler werden in Form von tracebacks ausgegeben; ein error ruft eine sogenannte exception hervor, wie z.B. ValueErrror, NameError, etc.
exception-handling wird ein eigenes Thema sein.

Wir werden auch Module, Klassen, packages kennenlernen.
Es gibt eine Art Konvention
Namen von Modulen/packages werden klein geschrieben, Namen von identifier klein geschrieben, Namen, die auf ein Funktionsobjekt zeigen, klein geschrieben (Unterstriche im Namen sind dann erwünscht, wenn das die Lesbarkeit des Namens verbessert), Class_Names --> capitalized plus jedes Teilwort capitalized (z.B.: class LotusBlume); und diese letzte Schreibweise nennt man auch CamelCase.

In python gibt es keinen Mechanismus, mit dessen Hilfe ich ein Objekt als Konstante deklarieren bzw. definieren kann (eine unveränderbare Größe, auf die ein Name zeigt).
Es gibt aber die Konvention im python Universum, dass komplett großgeschriebene identifier als Konstante angesehen werden --> PI, ERDRADIUS (wenn also identifier in upper-case, dann ist der identifier vom coder als Konstante getagged und kann von der Leserin als solche erkannt werden.)

int

int steht für integer und meint ganze Zahl, also KEINE Kommazahl, sondern plus/minus-Zahlen wie 5, -5, 8, +100,-1001.
int kann so groß werden, wie Du RAM in der Kiste hast - also Vorsicht! ;-)

seit python3 gibt int/int (ganze Zahl dividiert durch ganze Zahl) einen float (eine Gleitkommazahl) zurück.
soll int/int einen int (eine ganze Zahl) zurückgeben, dann geht das so

>>> print( type( 4/2 ) )
<class 'float'>
>>> print( type( 4 // 2) ) 
<class 'int'>
>>>

Außer 0 (null) dürfen/können ganze Zahlen NICHT mit einer 0 beginnen.

>>> 02
  File "<stdin>", line 1
    02
     ^
SyntaxError: invalid token
>>>  000
0
>>>

000 wird also als eine einzige Null erkannt und ausgegeben.
Es gibt die üblichen Operatoren + - * / % **
und natürlich auch die bit-Operatoren (1 Byte besteht aus 8bit, ein bit hat zwei Zustände, nämlich 0 oder 1, und bit-Operatoren verändern die 0 und 1 in einer bit-Folge. Ein bit SETZEN == von 0 auf 1 )

float

float meint Gleitkommazahlen (Kommazahlen).

>>> f = 12.2345666
>>> i = int(f)#floor von float
>>> print (i)
12
>>> s = str(f)#aus float ein str-Objekt machen
>>> print (s)
12.2345666
>>> print (type(s))
<class 'str'>
>>> s2 = '5'
>>> i2 = int(s2)
>>> print (i2)
5
>>> falsch = i2 + s2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 

es gibt zwar viele Freiheiten, aber auch hier darf man Kraut und Rüben nicht zusammen verarbeiten!

Das Ergebnis einer Rechnung kann manchmal auch unerwartet viele Nachkommastellen haben.

>>> print (.099)
0.099
>>> print (.1)
0.1
>>> print (.001)
0.001
>>>

Jetzt sollte man tatsächlich meinen, dass 0.1-0.099 0.001 ergibt.

>>> 0.1-0.099
0.0010000000000000009
>>>

Zu so einer Ausgabe (viele Nachkommastellen) kann es aus drei Gründen kommen:

>>> 0.01 - 0.009
0.0010000000000000009
>>> 0.009 + 0.0010000000000000009
0.01
>>>

Man verwendet Gleitkommazahlen primär für physikalische Messwerte wie Geschwindigkeit, Stromstärke, etc., eben weil die floats eine begrenzte Genauigkeit haben, diese Ungenauigkeit bei Messwerten fällt aber nicht ins Gewicht.
Exaktes Rechnen ist mit Gleitpunktzahlen im Allgemeinen nicht möglich.

Eine Kommazahl kann als Dezimalbruch (pointfloat) oder in exponentieller Schreibweise (exponentfloat) angegeben werden.

>>> print( 3.01E03) # 3.01 MAL 10hoch3 -> 3.01 * 1000
3010.0
>>> print( 3.01E-03)
0.00301
>>>

Übrigens, skuril auch, wie float (bzw. der py-Interpreter) mit vielen Nullen am Anfang der Kommazahl umgeht:

>>> 00000000.00000000
0.0
>>> 000000000.2020201
0.2020201
>>> 000000003.14159
3.14159
>>> bool(000000.000000)
False
>>>

round()

round() ist eine builtin-function und hilft uns beim Runden von Zahlen.
Man kann ganze Zahlen auf die Zehnerstelle, Hunderterstelle, etc. runden, oder Kommazahlen (floats) auf die erste Nachkommastelle (Zehntel), oder die zweite Nachkommastelle (Hundertstel), oder auch hier auf die Zehnerstelle, etc.
Hier sagen Beispiele wohl mehr als Tausend Worte.

>>> round(112.152728,3)
112.153
>>> round(112.152728,4)
112.1527
>>> round(112.152728,1)
112.2
>>> round(1123, -2)
1100
>>> round(1123, -1)
1120
>>> round(1123, -3)
1000
>>> round(1123, -5)
0
>>> round(1123, -20)
0
>>>

complex numbers

Auch die gibt es in python.
j ist dabei der imaginäre Teil (ich wollt es nur erwähnt haben)

>>> a = (5-2j)+(10+8j)
>>> print (a)
(15+6j)
>>> print (type(a))
<class 'complex'>
>>> print (a.real)
15.0
>>> print (a.imag)
6.0
>>> 

bin()

Mit Hilfe der builtin-function bin() kann man ganze Zahlen in Binaerzaehlen (bestehend aus 0, 1 -> Zahlen zur Basis 2) umwandeln. Zurückgegeben wird ein string, der mit '0b' oder 0B' beginnt, gefolgt vom bitstring.

>>> bin(73)
'0b1001001'
>>> bin(2.12)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'float' object cannot be interpreted as an integer
>>> help( bin )
 bin(...)
    bin(number) -> string
    
    Return the binary representation of an integer.
(END)

Hier geht es zum Seitenanfang und da geht es zur python-Übersicht