54
21.04.20 1 Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr Verteilte Anwendungen Teil P2: Objektorientierung und Ergänzungen

Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

21.04.20 1Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Verteilte Anwendungen

Teil P2: Objektorientierung und Ergänzungen

Page 2: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

2Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Überblick

� Klassen

� Scope

� Type Hints

� Dokumentation

� Datei I/O

� Exceptions

� print

� Unit-Tests

� Module und Packages

Page 3: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

3Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Klassen I

� Der Konstruktor hat den festen Namen __init__(self).

� Attribute brauchen nicht deklariert zu werden.

� Der erste schreibende Zugriff richtet Klassen-lokale Variablen ein.

� Der 1. Parameter der Methoden ist immer self; dessen Wert wird intern gesetzt.

� Zugriff auf Attribute im Inneren der Klasse erfolgt immer über self: self.name.

class ClassName(): ... Attribute ... def __init__(self, parameter1, parameter2, ...): Block def name(self, parameter1, parameter2, ...): Block def name(self, parameter1, parameter2, ...): Block

Page 4: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

4Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Bemerkungen

� self kann als ein Zeiger auf die interne Datenstruktur des Objektes angesehen werden.

� Warum dieser (interne) Zeiger nicht wie in Java und PHP per Compiler den Methoden mitgeteilt wird, ist unklar.

� Dieser self-Parameter wird beim Aufruf nicht angegeben.

� Zur Erzeugung des Objektes wird der Konstruktor mit dem Namen der Klasse ohne new aufgerufen.

Page 5: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

5Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Klassen II - Beispiel

class Rectangle(): def __init__(self,width,height): self.wdth= width self.hght= height def area(self): return self.wdth*self.hght def perimeter(self): return 2*(self.wdth+self.hght)

rec1= Rectangle(3,7)rec2= Rectangle(42,42)for r in [rec1, rec2]: print("Breite %4d Höhe %3d"%(r.wdth,r.hght)) print("Fläche %4d Umfang %3d"%(r.area(),r.perimeter()))

Breite 3 Höhe 7Fläche 21 Umfang 20Breite 42 Höhe 42Fläche 1764 Umfang 168

Output

Page 6: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

6Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Magische Methoden I

� Die Methode __str__ entspricht der toString()-Methode in Java.

� Der Unterschied zwischen __str__ und __repr__ besteht darin, dass letztere Methode immer das Objekt eindeutig machen muss, auch wenn es mehrere Bob Müllers gibt...

class Person(): def __init__(self,firstname: str,surname:str)-> None: self.firstname= firstname self.surname= surname def __str__(self): return f"{self.firstname}" def __repr__(self): return f"{self.firstname} {self.surname}"bm= Person("Bob","Müller")print(bm)print(f"{bm}")print(f"{bm!r}")

BobBobBob Müller

Output

Page 7: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

7Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Magische Methoden II

� __del__(self) ist der Destruktor, der beim Vernichten (nicht Freigeben) des Objekts aufgerufen wird.

� __delete__(self, instance) wird aufgerufen, wenn mit dem del-Kommando ein Attribut innerhalb eines bestehenden Objekts gelöscht wird.

� Siehe

– https://rszalski.github.io/magicmethods/

– https://www.geeksforgeeks.org/python-__delete__-vs-__del__

Diese Methoden werden auch Dander-Methoden genannt:Double Under (Underscores)

Es gibt viele magische Methoden, hier zwei weitere:

Page 8: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

8Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Sichtbarkeit von Attributen I

� id ist wie public

� _id ist wie protected

� __id ist wie private

Mit id als Attribut, Variable oder Funktion/Methode

� Die Eigenschaften von private, protected und public sind so wie in Java.

� Diese Schlüsselworte gibt es nicht in Python.� Das Ganze ist eine Konvention, an die sich gehalten werden

kann.� Die dritte Form dadurch privatisiert, dass dem Namen __id

intern ein anderer Name (zusammen mit dem Klassennamen) gegeben wird.

Page 9: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

9Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Sichtbarkeit von Attributen II

� Die Routine dir() liefert eine Liste aller definierten Symbole des Parameters – hier die Klasse Scope.

class scope(): att : int = 1 _att : int = 2 __att : int = 3

print(dir(scope))s= scope()s.att = 4s._att = 5s._scope__att = 6

['__annotations__', ... '_att', '_scope__att', 'att']

Output

Page 10: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

10Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Regeln zur Sichtbarkeit (Scope) I

� Local: innerhalb des Blocks oder Funktion, aber nicht als global erklärt

� Enclosing-function: Lokal innerhalb der Funktion bzw. Klasse, die die betroffene Funktion umschließen

� Global: global auf der höchsten Ebene (Modul, Package)

� Built-in (Python): In der Sprache bzw. Bibliotheken definiert

Regel LEGB

Also ganz normal, von Innen nach Außen gehend geht derSuchprozess bei der Bestimmung, welche Variable gemeint ist.

Alternative: Jede Variable hat einen eigenen Namen –dann ist immer klar, welche gemeint ist

Page 11: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

11Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Regeln zur Sichtbarkeit (Scope) II

� Lokale Zuweisungen an globale Variablen verhalten sich genauso wie in PHP und Java.

� Globale Variablen können lokal benutzt werden.

a = 1def fn(): a = 2 print(a)fn()print(a)

22

Output

a = 1def fn(): #a = 2 print(a)fn()print(a)

11

Output

Page 12: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

12Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Regeln zur Sichtbarkeit (Scope) III

� Die erste lokale Zuweisung richtet eine Variable lokal ein.

� Mit dem Schlüsselwort global kann auch lokal eine globale Variable eingerichtet und lokal benutzt werden.

def fn(): a = 2 print(a)fn()print(a)

NameError: name 'a' is not defined

Output

def fn(): global a a = 2 print(a)fn()print(a)

22

Output

Page 13: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

13Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Regeln zur Sichtbarkeit (Scope) IV

� https://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html

� https://www.datacamp.com/community/tutorials/scope-of-variables-python

� https://people.cs.clemson.edu/~malloy/courses/pythonProg-2015/lessons/scope/paper.pdf

Siehe

Page 14: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

14Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Vererbung I - Einfach

� Vererbung erfolgt über den Parameter bei der Klassendefinition.

� Es ist mehrfache Vererbung erlaubt.

class ClassName(UppClass1, ...): ... Attribute ... def __init__(self, parameter1, parameter2, ...): Block def name(self, parameter1, parameter2, ...): Block def name(self, parameter1, parameter2, ...): Block

Page 15: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

15Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Vererbung II - super

� Das Aufrufen des Konstruktors erfolgt über super() oder wie links angegeben.

� Der Effekt ist derselbe.

class Parent(): def __init__(self): print('Parent.__init__()')class Child(Parent): def __init__(self): Parent.__init__(self) print('Child.__init__()')c= Child()

class Parent(): def __init__(self): print('Parent.__init__()')class Child(Parent): def __init__(self): super().__init__() print('Child.__init__()')c= Child()

Parent.__init__()Child.__init__()

Output

Page 16: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

16Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Vererbung III - Mehrfach

� Wenn keine Methode überschrieben wird, d.h. wenn alle Namen eindeutig sind, ist die Welt in Ordnung.

(01) class A():(02) def a(self):(03) print('A.a()')(04) class B():(05) def b(self):(06) print('B.b()')(07) class C(A,B):(08) def c(self):(09) print('C.c()')(10) c= C(); c.a(); c.b(); c.c()

A.a()B.b()C.c()

Output

Page 17: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

17Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Vererbung IV - Mehrfach

� Jetzt stehen zwei Methoden Namens a zur Verfügung.

� Es wird die Liste der Oberklassen in der Reihenfolge der Angabe durchsucht bis eine Methode mit dem richtigen Namen gefunden wird.

(01) class A():(02) def a(self):(03) print('A.a()')(04) class B():(05) def a(self):(06) print('B.a()')(07) class C(A,B):(08) def c(self):(09) print('C.c()')(10) c= C(); c.a(); c.c()

A.a()C.c()

Output

Page 18: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

18Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Vererbung V - Mehrfach

� Wenn die konkurrierenden Methoden überschrieben werden, wird es wieder einfach.

(01) class A():(02) def a(self):(03) print('A.a()')(04) class B():(05) def a(self):(06) print('B.a()')(07) class C(A,B):(08) def a(self):(09) print('C.a()')(10) c= C(); c.a();

C.a()Output

Page 19: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

19Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Was ist None?

� Das Keyword None dient zur Darstellung von Null (wie in PHP und Java).

� Es kann allen Variablen und Objekten zugewiesen werden.

� None hat den Wert None und ist vom Typ NoneType (analog zu PHP).

� None ist konsequenterweise ein Objekt.

Page 20: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

20Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints I

class Rectangle(): wdth : float hght : float def __init__(self,width: float,height: float): self.wdth= width self.hght= height def area(self) -> float: return self.wdth*self.hght def perimeter(self) -> float: return 2*(self.wdth+self.hght) for r in [Rectangle(3.0,7.0),Rectangle(42.0,42.0)]: print("Breite %4.2f Höhe %3.2f"%(r.wdth,r.hght)) print("Fläche %4.2f Umfang %3.2f"%(r.area(),r.perimeter()))

Breite 3.00 Höhe 7.00Fläche 21.00 Umfang 20.00Breite 42.00 Höhe 42.00Fläche 1764.00 Umfang 168.00

Output

Page 21: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

21Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints II

� Syntax:

– Parameter : Type

– Funktionsresultat -> Type

– Variable : Type = , z.B. a : int = 10

� Für Type kann stehen:

– Basistyp: int, float, bool und str für String

– Klassennamen (nicht rekursiv die eigene Klasse)

– None

– Konstrukt aus Modul Typing

� Type hints sind für Python nur Hinweise. Einzig gute IDE werten diese aus:

Page 22: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

22Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints III – Modul Typing

� Siehe: https://docs.python.org/3/library/typing.html

� Zusammenfassung von Alternativen mittels Union

from typing import Union

def myFunc(param : int) -> Union[str,float]: if param>=0: return float(param) else: return "negative"

print(myFunc(3))print(myFunc(-5))

from typing import Optional

def myFunc(param: Optional[int]= -1): if param==-1: print(param) else: print('no parameter')

myFunc(3)myFunc()

Beispiel füroptionaleParameter

Page 23: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

23Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints IV – Modul Typing

� Angabe einer Liste und eines Dictionaries

from typing import List

def printNames(names: List[str]) -> None: for student in names: print(student)

printNames(['Alice','Bob'])

from typing import Dict

def printStudents(students: Dict[str, int]) -> None: for student, age in students.items(): print(student, age)

printStudents({"age": 22})

Page 24: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

24Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints V – Modul Typing

� Angabe eines Tupels

from typing import Tuple

def mod(a: int, b: int) -> Tuple[int, bool]: if b != 0: return a%b, True else: return 0, False

print(mod(16,5))print(mod(9,0))

(1, True)(0, False)

Output

Page 25: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

25Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Type hints VI – __annotations__

� In der Eigenschaft __annotations__ sind die Type-Hints in Form eines Dictionaries abgespeichert.

from typing import Union

def myFunc(param : int) -> Union[str,float]: if param>=0: return float(param) else: return "negative"

print(myFunc.__annotations__)

{'param': <class 'int'>, 'return': typing.Union[str, float]}Output

Page 26: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

26Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Style Guides

� Offiziell: https://www.python.org/dev/peps/pep-0008/

– Cheat Sheet: https://gist.github.com/RichardBronosky/454964087739a449da04

– Zusammenfassunghttp://gki.informatik.uni-freiburg.de/teaching/info1_guide/styleguide.html

� Auch

– http://google.github.io/styleguide/pyguide.html

Page 27: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

27Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit %-Formatstring I

� Syntax 'Format-String' % (Tupel)

� In der Syntax %X wird der Typ sowie das Format angegeben: %[flags][width][.precision]type

� Für type sind üblich %d (int), %f (Float), %s (String), %c (char) und %% für %.

� Die Anzahl der % im Formatstring muss gleich der Anzahl der Elemente im Tupel sein.

print('%d mit mod %d' %(x,y))

Format-String

Werte ineinem Tupel

Page 28: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

28Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit %-Formatstring II

� Das Ende der Zeile sowie die Zeichenkette zwischen den Bestandteilen kann frei definiert werden (Default):

� Syntax mit den Default-Werten:print(Objekte, sep=' ', end='\n')

� Siehe

– https://www.python-kurs.eu/python3_formatierte_ausgabe.php

print(2, end='')print('**',4, sep='', end=' ')print('=', 2**4)

Output 2**4 = 16

Page 29: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

29Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit format() I

� Die Format-Funktion interpretiert den Formatstring und generiert einen Ausgabe-String, der auch in String-Variablen abgelegt werden kann.

� Die Platzhalter sind hier {}.

a= 10b= 3print('{} mod {} = {}'.format(a,b,a%b))c= '{} mod {} = {}'.format(a,b,a%b)print(c)

10 mod 3 = 110 mod 3 = 1

Output

Page 30: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

30Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit format() II

� Die Platzhalter können benannt werden, so dass die Reihenfolge der Werte beliebig sein kann.

� Den Namen der Platzhalter werden dann die Werte zugeordnet.

student= {"Name": "Alice", "Age": 22}print('{name} ist {age} Jahre alt' \ .format(name= student["Name"], \ age= student["Age"]))

Alice ist 22 Jahre alt

Output

Page 31: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

31Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit f-Strings I

� Die f-Strings haben Platzhalter, in denen Python-Konstrukte für den Zugriff auf Variablen stehen, also ganz ähnlich wie in PHP.

� Dadurch wird alles etwas kürzer.

� Wenn – wie in dem Beispiel – ein String innerhalb des Strings vorkommt, dann müssen die jeweils alternativen Stringbegrenzer (" oder ') benutzt werden.

� Die f-Strings können direkt hintereinander ohne die Aufhebung des Zeilenendes in mehreren Zeilen geschrieben werden.

student= {"Name": "Alice", "Age": 22}print(f"{student['Name']} ist {student['Age']} Jahre alt")print(f"{student['Name']} ist " f"{student['Age']} Jahre alt")

Page 32: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

32Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

print() mit f-Strings II

� Es sind auch Aufrufe von Funktionen bzw. Ausdrücke innerhalb der {}-Klammern erlaubt.

student= {"Name": "Alice", "Age": 22}print(f"{student['Name'].upper()} ist " f"{student['Age']+2} Jahre alt")

ALICE ist 24 Jahre alt

Output

Page 33: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

33Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Dokumentation I

� help(...) gibt die Signatur sowie den direkt darunter im String stehenden Text aus.

� Auf diesen String kann über die Eigenschaft __doc__ zugegriffen werden (ohne die Signatur).

� Siehe: https://www.python.org/dev/peps/pep-0257/

def toDoc(param: int) -> None: """ this function has a doc

Only one parameter of type int """

print(param)

help(toDoc)print('-------------------------')print(toDoc.__doc__)

Startzeile

Leerzeile

Beschreibung

Help on function toDoc in module __main__:

toDoc(param: int) -> None this function has a doc Only one parameter of type int

Page 34: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

34Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Dokumentation II

� Diese so Doc-String genannten Beschreibungen stehen

– zum Beginn der Datei

– direkt hinter der class-Zeile

– direkt hinter der Funktionszeile (def)

Page 35: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

35Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Datei I/O I - Beispiel

fn= "data.txt"ofile = open(fn, "w")for x in range(11): ofile.write(str(x**x)+"\n")ofile.close()ifile = open(fn, "r")s = ifile.read()print(s)

Output 114272563125466568235431677721638742048910000000000

fd= open(Filename,Mode) Eröffnen

fd.read() Lesen

fd.write Schreiben

fd.close() Schließen

fd.readline() 1 Zeile

fd.readlines() Alle Zeilen in eine Liste

Page 36: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

36Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Datei I/O II - Beispiel

ifile = open("data.txt", "r")s = ifile.readline()print (s)s = ifile.readlines()print (s)

Output

Datei 114272563125466568235431677721638742048910000000000

1['1\n', '4\n', '27\n', '256\n', '3125\n','46656\n', '823543\n', '16777216\n','387420489\n', '10000000000\n']

Page 37: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

37Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Exceptions I

� Das Verfahren in Python ist dem in PHP (und etwas dem von Java) sehr ähnlich.

� Es gibt den Try-Block (4) und den Catch-Block (6).

� Hinter Except steht dann der Name der Exception oder nichts mit der Bedeutung, dass alle Exceptions gemeint sind (5).

� Hinweis: Zeilen (4) und (6) führen zu verschiedenen Datentypen.

(1) a = 10(2) for b in [17, 0, -9]:(3) try:(4) d = a // b(5) except:(6) d = None(7) print(f"{a}//{b} = {d} ")

Output

10//17 = 0 10//0 = None 10//-9 = -2

Page 38: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

38Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Exceptions II

� Es kann eine Kaskade von except-Blöcken, jeweils mit der Angabe der Exception an den Try-Block gehängt werden.

� Die except-Blöcke werden sequentiell geprüft; d.h. das Fangen aller Exceptions (10) muss immer am Ende stehen.

� Mit raise ohne Parameter wird die Exception weitergegeben.

(01) import sys(02) try:(03) fd = open('file42.txt')(04) line = fd.readline()(05) i = int(line.strip())(06) except IOError as e:(07) print(e)(08) except ValueError:(09) print("No integer data")(10) except:(11) print("Unknown error:", sys.exc_info()[0])(12) raise

Page 39: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

39Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Exceptions III - Werfen

� Es wird eine von Exception abgeleitete Klasse definiert (1).

� Das pass in (2) bedeutet, dass dieser Teil leer ist.

� In (3) wird diese leere Klasse mit einem Erklärungsstring als ersten Parameter mit raise geworfen.

(1) class MyException(Exception):(2) pass

(3) raise MyException("Murphy!")

Output

Traceback (most recent call last): File "D:\bmesser\...\exception3.py", line 4, in <module> raise MyException("Murphy!")MyException: Murphy!

Page 40: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

40Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Exceptions IV - Syntax

� Wie in Java/PHP wird der finally-Block immer ausgeführt und kann weggelassen werden.

� Die Catch-Blöcke können aus einem except-Block bestehen.

� Der else-Block wird nur dann ausgeführt, wenn keine Exception auftrat.

try: Block1except: Block2

try: Block1except ExceptionClass1: Block2except ExceptionClass2: Block3... except: BlockNfinally: BlockN+1

try: Block1except: Block2finally: Block3

try: Block1except: Block2else: Block3

try: Block1except: Block2else: Block3finally: Block4

Page 41: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

41Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests I – für arme Leute

� Die Funktion berechnet eine Quersumme einer Zahl, die als String in Dezimalform gegeben ist.

� assert prüft, ob eine Bedingung erfüllt ist. Falls ja, passiert nichts, falls nein, wird eine Fehlermeldung mit dem 2. Parameter ausgegeben und das Programm abgebrochen.

def checksum(s: str) -> int: sum= 0 for c in s: sum+= int(c) return sum

def testCs(): assert checksum("123") == 6, "Should be 6" if __name__ == "__main__": testCs()print("All tests passed")

Page 42: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

42Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests II – für arme Leute

� Die Fehlermeldung ist noch mit einem Stack-Trace, d.h. mit Informationen über die Aufruf-Situation versehen.

def checksum(s: str) -> int: sum= 1 for c in s: sum+= int(c) return sum

....

Fehler

Output Traceback (most recent call last): File "D:\bmesser\...", line 11, in <module> testCs() File "D:\bmesser\...", line 8, in testCs assert checksum("123") == 6, "Should be 6"AssertionError: Should be 6

Page 43: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

43Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Zwischenbemerkung I

� __name__ hat den Namen des Moduls als Inhalt.

� Wird das Skript über die Kommandozeile aufgerufen, so ist der Modulname immer '__main__'.

� Wenn es aus einer Datei importiert wurde, dann enthält __name__ den Dateinamen.

if __name__ == "__main__": testCs()

Was bedeutet das?

if __name__ == '__main__': print('Das Skript läuft allein')else: print('Das Skript wurde importiert')

Page 44: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

44Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Zwischenbemerkung II – noch etwas

� Das Modul sys realisiert den Zugriff auf die Umgebung.

– sys.argv ist eine Liste mit den Aufrufparametern

– sys.path ist eine Liste mit den Ordnern, die zum Laden durchsucht werden.

– sys.stout.write ist primitive print mit einem String.

import syssys.stdout.write('Die Parameter sind: ')for arg in sys.argv: sys.stdout.write(arg+' ')print('\n\n' 'Der PYTHONPATH ist',sys.path)

Zugriff auf dieParameterbei Aufruf im Shell

D:\bmesser\...0-Progs>python argv1.py a b cDie Parameter sind: argv1.py a b c

Der PYTHONPATH ist ['D:\\bmesser\\...0-Progs',... 'C:\\Program Files (x86)\\Python38-32', ... C:\\Program Files (x86)\\Python38-32\\lib\\site-packages']

D:\bmesser\...0-Progs>

Output

Page 45: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

45Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests III – Modul unittest

� Zwei Dinge

– Eine Klasse, die testet

– Ein Modul bzw. eine Klasse, die getestet wird

(1) import unittest(2) from checksum import checksum

(3) class TestChecksum(unittest.TestCase):(4) def test1(self):(5) self.assertEqual(checksum("123"), 6, "Should be 6")(6) if __name__ == "__main__":(7) unittest.main()

def checksum(s: str) -> int: sum= 0 for c in s: sum+= int(c) return sum

Datei checksum.py

Datei ctest1.py

(A) .(B) -----------------------(C) Ran 1 test in 0.000s

(D) OK

Output

Page 46: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

46Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Erläuterungen der Testklasse

� In (1) wird die Testumgebung importiert.

� In (2) wird das zu testende Modul bzw. Klasse importiert. Die erfolgt durch den Namen (ohne .py) einer Datei, die im Lade-Pfad (PYTHONPATH) liegt.

� In (3) wird die Testklasse als Unterklasse der Testumgebung (TestCase) definiert.

� Für jeden Test wird eine Methode geschrieben, in der über die assert-Routinen das Ergebnis eines Aufrufs geprüft wird.

� In (5) steht der assert-Aufruf.

� Der Testtreiber wird in (7) aufgerufen.

� Beim Output in Zeile (A) steht ein Zeichen für einen Test: . Bedeutet OK, F bedeutet Fail und E bedeutet sonstiger Fehler.

� Siehe: https://docs.python.org/3/library/unittest.html

Page 47: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

47Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Reguläre Pakete I

� Um die Testdinge von den Realisierungsdingen zu trennen gibt es die Pakete (regular packages), die ähnlich zu Java sind.

� Ein Paket besteht aus den Dateien eines Ordners (im Pfad), der neben den Modulen und Klassen jeweils in Dateien eine Datei Namens __init__.py enthält.

� Beim Import des Paketes wird diese Datei ausgeführt. Dort stehen dann die Imports der Elemente des Paketes.

from .checksum import checksum

Datei __init__.py

Der Punkt istsehr wichtig

D:.| TestChecksum.py| \---crc checksum.py __init__.py

Test-Klasse

PaketDas Paket unseres Beispiels sollecrc heißen...

Page 48: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

48Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Reguläre Pakete II

� In den Ordner crc kommen dann noch alle weiteren Realisierungen von Checksummen hinzu.

� In der Datei __init__.py wird gewissermaßen das Public-Interface des Pakets definiert. Alles, was hier nicht importiert wird, ist dann Paket-lokal.

import crc class TestChecksum(unittest.TestCase): def test1(self): self.assertEqual(crc.checksum("123"), ...)

from crc import *class TestChecksum(unittest.TestCase): def test1(self): self.assertEqual(checksum("123"), ...)

Mit dem Paket crc sehen die Testklassen so aus:

Page 49: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

49Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests IV – Modul unittest

Funktion Erläuterung Negation

assertEqual(a, b) a == b assertNotEqual(a, b)

assertTrue(x) bool(x) is True assertFalse(x)

assertIs(a, b) a is b assertIsNot(a, b)

assertIsNone(x) x is None assertIsNotNone(x)

assertIn(a, b) a in b assertNotIn(a, b)

assertIsInstance(a, b) isinstance(a, b) assertNotIsInstance(a, b)

assertListEqual(a, b)

assertTupleEqual(a, b)

assertDictEqual(a, b)

Bei allen Routinen kann ein hier nicht angegebener String-Parameterzur Erläuterung des Tests hinten angefügt werden (Empfehlenswert).

Page 50: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

50Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests V – Modul unittest Exceptions

� Die checksum-Routine mit einer Fehlerbehandlung.

class CRCException(Exception): pass

def checksumExcept(s: str) -> int: sum= 0 for c in s: if c.isdigit(): sum+= int(c) else: raise CRCException('no digit') return sum

Page 51: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

51Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests VI – Modul unittest Exceptions

� Das ist das übliche Muster (Pattern) für Tests auf das Werfen von Exceptions.

� Fail() signalisiert, dass der Test schief geht.

� Bei der Behandlung der richtigen Exception steht pass.

import unittestfrom crc import *class TestExcept(unittest.TestCase): def test1(self): try: checksumExcept("A23") self.fail('CRCException exspected') except CRCException: pass except: self.fail('CRCException not raised')...

Page 52: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

52Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests VII – Modul unittest Exceptions

� Das ist die verkürzte Version: hinter dem with steht der zu testende Aufruf.

� Der Parameter zu assertRaises ist der Name der Exception(-Klasse).

� With eröffnet einen Kontext für das, was hinter dem with steht.

� Siehe: https://docs.python.org/3/reference/compound_stmts.html

import unittestfrom crc import *

class TestExcept(unittest.TestCase): def test1(self): with self.assertRaises(CRCException): checksumExcept("A23")

Page 53: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

53Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Unit-Tests VIII – Modul unittest

In jeder Testklasse gibt es noch die Möglichkeit für

setUp() wird vor jeder Testmethode aufgerufen und baut

das Fixture (Testumgebung) auf.

tearDown() baut das Fixture nach jeder Testmethode ab.

setUpClass() wird vor jeder Testklasse aufgerufen.

tearDownClass() wird nach allen Methoden einer Testklasse

aufgerufen.

skipTest(Grund) bewirkt das Auslassen eines Tests. Syntax:

https://docs.python.org/3/library/unittest.html#un

ittest-skipping

fail(Grund) signalisiert einen gescheiterten Test.

Der explizite Auf- und Abbau eines Fixtures (Umgebung) ist beiexterne Ressourcen (Dateien, Netze, Datenbanken) notwendig.Wichtig: Keine Seiteneffekte beim Testen!Alle Test können in beliebiger Reihenfolge ausgeführtwerden.

Page 54: Verteilte Anwendungen Teil P2: Objektorientierung und ...wi.f4.htw-berlin.de/users/messer/LV/WI-AVS-SS20/Folien/P2/VA-P2-O… · Verteilte Anwendungen – SS 2020 – Teil P2/Objekte

54Verteilte Anwendungen – SS 2020 – Teil P2/Objekte und mehr

Nun wieder etwas entspannen...