Objekte in Python

1. Literatur:

2. Grober Überblick:

Drei Sprach-Features:
Unterschied zu anderen Sprachen:
Beispiel: Berechnung von Pi auf 1000 Stellen
#!/usr/bin/python
def a(n):                       # arctan(1/n)
    t = base/n; q = -n*n; x = t/q

    i = 3l
    while x != 0:
        t += x/i; x /= q
        i += 2
    return t

dig = 1000                      # 1000 Stellen
base = 10l**(dig+10)
s = 48*a(18) + 32*a(57) - 20*a(239)
print s

Rechenzeit: max. 50ms (Athlon XP 1700) ... schnell!

Download: www.sax.de/unix-stammtisch/..., lynx --> p (print)

Also:
Datentypen:

Skalar:

char, int, inf long; float=double, complex

Sequenzen:





Konstant:





Strings:

'abc', "abc", 'ein "Wort"', """über

Zeilengrenze hinaus"""



Unicodes:

u'abc'



Tupel:

(1, 2, 'abc')

(beliebige Typen aneinandergereiht, aber Konstante)


veränderlich:





Listen:

a = [1, 2, 'abc']; a[2] = 3; print a

[1, 2, 3]

Mappings:





Dictionaries:


{ 'Bernd' : 80.2, 'Antonia' : 77.3, ...}

(assoziatives Feld, Schlüssel muss konst. sein)

Aufrufbare Typen:




Funktionen, Klassen, Methoden (Funktion in Klasse)

Klassen




Files:



fd = open('diddi', 'r'); rec = fd.readline(); ...

Besonderheit:

Methoden und Attribute; Attribute sind wie Strukturelemente bei C, Bezeichnung »a.c«;

manche Attribute sind Funktionen und heißen dann Methoden ... (auch nur ein Datentyp)

Methoden gibt es bei Klassen und Modulen (die wie Klassen angesprochen werden).

Listenverarbeitung:

Slices:


a = 'abcd'
a[1:]   'bcd'
a[1:2]  'bc'
a[:-1]  'abc'

Methoden für Listen:


a = 'Eene|meene|muh'
b = a.split('|')
print b
['Eene', 'meene', 'muh']
from string import join
print join(b,'*')
Eene*meene*muh

map:

def f2(x):
    x *= 2
    return x

a = (1,2,3); b = map(f2, a); print b
[2, 4, 6]

Weiter: reduce, filter;


Listenverarbeitung beschleunigt Python erheblich!

3. Klassen

Praktisches Beispiel - Gewichtsmittelung in einer Leistungssport-WG


Aufgabe: Jeder wiegt sich täglich; am Ende sollen die Kurven von n-Tage-Mitteln ausgegeben werden (n ist personenspezifisch).

Als Programm mit Fallunterscheidungen und mehrdimensionalen Feldern, als Klasse einfach:

#!/usr/bin/python

class Mean:
    def __init__(self, len):
        self.len = len               # days for mean computing
        self.cv = []
        self.cnt = 0

    def mean(self, nr, date, mass):       # nr = int, mass = float
        if not self.cv:
            self.s = self.len*[mass]
            self.sum = self.len*mass

        self.sum += mass - self.s[self.cnt]
        self.s[self.cnt] = mass
        self.cnt = (self.cnt+1)%self.len
        self.cv.append('%d %s %.2f' % (nr, date, self.sum/self.len))

# Instanzen erzeugen
bernd = Mean(10)                # Ruf von __init__(10)
antonia = Mean(3)

# Gewichte eingeben
bernd.mean(1, '1.1.04', 82)
antonia.mean(2, '1.1.04', 78.2)
bernd.mean(1, '2.1.04', 83.4)
antonia.mean(2, '2.1.04', 77.9)
bernd.mean(1, '3.1.04', 84.8)
antonia.mean(2, '3.1.04', 77.8)
bernd.mean(1, '4.1.04', 83)
antonia.mean(2, '4.1.04', 77.2)

#Ausgaben erzeugen
print "Bernd:"
for s in bernd.cv: print s
print "\nAntonia:"
for s in antonia.cv: print s

# Ausgabe:

Bernd:
1 1.1.04 82.00
1 2.1.04 82.14
1 3.1.04 82.42
1 4.1.04 82.52

Antonia:
2 1.1.04 78.20
2 2.1.04 78.10
2 3.1.04 77.97
2 4.1.04 77.63

Beispiel aus dem realen Leben: virtueller Filepointer mit evtl. Umleitung und "less"


# return file object for redirection
# (usually pipeline, evtl. with 'tee' and 'less')
# arg: filename - default; if none then no request for redirection

class redirect:
    def __init__(self, name=None):
        self.out = ''
        if name and io.yask('Ausgabe auf File umlenken', 'n'):
            while 1:
                file = io.dask('Ausgabe auf', name)
                if os.access(file, os.F_OK):
                    if os.access(file, os.W_OK):
                        if not io.yask(file + \
                                ' existiert bereits - überschreiben', 'n'):
                            continue
                    else:
                        io.error(file + ' ist nicht beschreibbar')
                        continue
                break
            self.out = 'tee ' + file + ' | '

        self.out += 'less -F'

    def open(self):
        self.__fd = os.popen(self.out, 'w')

    def write(self, string):
        if self.__fd:
            try:
                self.__fd.write(string)
            except IOError:
                self.__fd.close()
                self.__fd = None

    def close(self):
        if self.__fd :
            try:
                self.__fd.close()
            except IOError:
                pass

Benutzung:

fd = redirect('Stamm.hmtl')
# ... do something ...
fd.open()               # "less" zerhaut den Bildschirm!!
fd.write('<it>meine erste Zeile<(it>');
# ...
fd.close()

4. Besonderheiten von Klassen:


import time

class min_sec:
    ti = time.strftime('%M:%S')
    def tr(self):
         return time.strftime('%M:%S')

a1 = min_sec()
print a1.ti
12:17
print a1.tr()
12:21
# einige Zeit warten ...
a2 = min_sec()
print a2.ti
12:17
print a2.tr()
12:28
Achtung beim Programmieren: