mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-04-27 07:33:57 +00:00
Kap. 5+6 aktualisiert, Kap 6.1, 6.2, 7 hinzugefügt
Kapitel 6.1, 6.2 und 7 aus der englischen Version übernommen. Kapitel 5 und 6 getauscht, um der englischen Version zu entsprechen. Texte der Kapitel 5 und 6 Kapitel um fehlende Teile erweitert.
This commit is contained in:
parent
2dde374091
commit
c0c2272be0
@ -386,58 +386,9 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
|
||||
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
|
||||
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
|
||||
|
||||
####################################################
|
||||
## 5. Klassen
|
||||
####################################################
|
||||
|
||||
# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten.
|
||||
class Human(object):
|
||||
|
||||
# Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
|
||||
species = "H. sapiens"
|
||||
|
||||
# Ein simpler Konstruktor
|
||||
def __init__(self, name):
|
||||
# Wir weisen das Argument name dem name-Attribut der Instanz zu
|
||||
self.name = name
|
||||
|
||||
# Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument.
|
||||
def say(self, msg):
|
||||
return "%s: %s" % (self.name, msg)
|
||||
|
||||
# Eine Klassenmethode wird von allen Instanzen geteilt.
|
||||
# Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
|
||||
@classmethod
|
||||
def get_species(cls):
|
||||
return cls.species
|
||||
|
||||
# Eine statische Methode wird ohne Klasse oder Instanz aufgerufen
|
||||
@staticmethod
|
||||
def grunt():
|
||||
return "*grunt*"
|
||||
|
||||
|
||||
# Eine Instanz einer Klasse erstellen
|
||||
i = Human(name="Ian")
|
||||
print i.say("hi") # gibt "Ian: hi" aus
|
||||
|
||||
j = Human("Joel")
|
||||
print j.say("hello") #gibt "Joel: hello" aus
|
||||
|
||||
# Rufen wir mal unsere Klassenmethode auf
|
||||
i.get_species() #=> "H. sapiens"
|
||||
|
||||
# Ändern wir mal das gemeinsame Attribut
|
||||
Human.species = "H. neanderthalensis"
|
||||
i.get_species() #=> "H. neanderthalensis"
|
||||
j.get_species() #=> "H. neanderthalensis"
|
||||
|
||||
# Aufruf der statischen Methode
|
||||
Human.grunt() #=> "*grunt*"
|
||||
|
||||
|
||||
####################################################
|
||||
## 6. Module
|
||||
## 5. Module
|
||||
####################################################
|
||||
|
||||
# Wir können Module importieren
|
||||
@ -461,11 +412,339 @@ math.sqrt(16) == m.sqrt(16) #=> True
|
||||
# können unsere eigenen schreiben und importieren. Der Name des
|
||||
# Moduls ist der Dateiname.
|
||||
|
||||
# Wir können auch die Funktionen und Attribute eines
|
||||
# Moduls herausfinden.
|
||||
# Wir können herausfinden, welche Funktionen und Attribute in einem
|
||||
# Modul definiert sind.
|
||||
import math
|
||||
dir(math)
|
||||
|
||||
# Wenn Sie ein Python-Skript namens math.py im selben Ordner
|
||||
# wie Ihr aktuelles Skript haben, wird die Datei math.py
|
||||
# anstelle des integrierten Python-Moduls geladen.
|
||||
# Dies geschieht, weil der lokale Ordner Vorrang
|
||||
# vor den in Python integrierten Bibliotheken hat.
|
||||
|
||||
|
||||
####################################################
|
||||
## 6. Klassen
|
||||
####################################################
|
||||
|
||||
# Wir verwenden das Schlüsselwort "class" um eine Klasse zu erzeugen.
|
||||
class Human(object):
|
||||
|
||||
# Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
|
||||
species = "H. sapiens"
|
||||
|
||||
# Ein simpler Konstruktor, wird aufgerufen, wenn diese Klasse instanziiert wird.
|
||||
# Beachten Sie, dass die doppelten vorangestellten und nachgestellten
|
||||
# Unterstriche Objekte oder Attribute bezeichnen, die von Python verwendet werden,
|
||||
# aber in benutzergesteuerten Namespaces leben.
|
||||
# Methoden (oder Objekte oder Attribute) wie: __init__, __str__, __repr__ usw.
|
||||
# werden als Sondermethoden (oder manchmal als Dundermethoden bezeichnet) bezeichnet.
|
||||
# Sie sollten solche Namen nicht selbst erfinden.
|
||||
def __init__(self, name):
|
||||
# Wir weisen das Argument name dem name-Attribut der Instanz zu
|
||||
self.name = name
|
||||
|
||||
# Eine Instanzmethode. Alle Methoden erhalten "self" als erstes Argument.
|
||||
def say(self, msg):
|
||||
return "%s: %s" % (self.name, msg)
|
||||
|
||||
# Eine weitere Instanzmethode
|
||||
def sing(self):
|
||||
return 'yo... yo... microphone check... one two... one two...'
|
||||
|
||||
# Eine Klassenmethode wird von allen Instanzen geteilt.
|
||||
# Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
|
||||
@classmethod
|
||||
def get_species(cls):
|
||||
return cls.species
|
||||
|
||||
# Eine statische Methode wird ohne Klasse oder Instanz aufgerufen
|
||||
@staticmethod
|
||||
def grunt():
|
||||
return "*grunt*"
|
||||
|
||||
# Eine Eigenschaft (Property) ist wie ein Getter.
|
||||
# Es verwandelt die Methode age() in ein schreibgeschütztes Attribut mit demselben Namen.
|
||||
# Es ist jedoch nicht nötig, triviale Getter und Setter in Python zu schreiben.
|
||||
@property
|
||||
def age(self):
|
||||
return self._age
|
||||
|
||||
# Damit kann die Eigenschaft festgelegt werden
|
||||
@age.setter
|
||||
def age(self, age):
|
||||
self._age = age
|
||||
|
||||
# Damit kann die Eigenschaft gelöscht werden
|
||||
@age.deleter
|
||||
def age(self):
|
||||
del self._age
|
||||
|
||||
# Wenn ein Python-Interpreter eine Quelldatei liest, führt er den gesamten Code aus.
|
||||
# Diese __name__-Prüfung stellt sicher, dass dieser Codeblock nur ausgeführt wird,
|
||||
# wenn dieses Modul das Hauptprogramm ist.
|
||||
if __name__ == '__main__':
|
||||
# Eine Instanz einer Klasse erstellen
|
||||
i = Human(name="Ian")
|
||||
i.say("hi") # "Ian: hi"
|
||||
j = Human("Joel")
|
||||
j.say("hello") # "Joel: hello"
|
||||
# i und j sind Instanzen des Typs Mensch, oder anders ausgedrückt: Sie sind Objekte des Menschen
|
||||
|
||||
# Rufen wir unsere Klassenmethode auf
|
||||
i.say(i.get_species()) # "Ian: H. sapiens"
|
||||
|
||||
# Ändern wir das gemeinsame Attribut
|
||||
Human.species = "H. neanderthalensis"
|
||||
i.say(i.get_species()) # => "Ian: H. neanderthalensis"
|
||||
j.say(j.get_species()) # => "Joel: H. neanderthalensis"
|
||||
|
||||
# Aufruf der statischen Methode
|
||||
print(Human.grunt()) # => "*grunt*"
|
||||
|
||||
# Kann keine statische Methode mit Instanz des Objekts aufrufen,
|
||||
# da i.grunt () automatisch "self" (das Objekt i) als Argument verwendet
|
||||
print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
|
||||
|
||||
# Die Eigenschaft für diese Instanz aktualisieren
|
||||
i.age = 42
|
||||
# die Eigenschaft auslesen
|
||||
i.say(i.age) # => "Ian: 42"
|
||||
j.say(j.age) # => "Joel: 0"
|
||||
# die Eigenschaft löschen
|
||||
del i.age
|
||||
# i.age # => würde einen AttributeError werfen
|
||||
|
||||
####################################################
|
||||
## 6.1 Inheritance
|
||||
####################################################
|
||||
|
||||
# Vererbung ermöglicht die Definition neuer untergeordneter Klassen,
|
||||
# die Methoden und Variablen von ihrer übergeordneten Klasse erben.
|
||||
|
||||
# Wenn Sie die oben definierte Human-Klasse als Basis- oder Elternklasse verwenden,
|
||||
# können Sie eine untergeordnete Klasse, Superhero, definieren, die die Klassenvariablen
|
||||
# wie "species", "name" und "age" sowie Methoden wie "sing" und "grunzen" aus der Klasse Human erbt.
|
||||
# Die Untergeordnete Klasse kann aber auch eigene Eigenschaften haben.
|
||||
|
||||
# Um von der Modularisierung per Datei zu profitieren, können Sie die Klassen
|
||||
# in ihren eigenen Dateien platzieren, z. B. human.py
|
||||
|
||||
# Um Funktionen aus anderen Dateien zu importieren, verwenden Sie das folgende Format
|
||||
# from "Dateiname-ohne-Erweiterung" impotr "Funktion-oder-Klasse"
|
||||
|
||||
from human import Human
|
||||
|
||||
# Geben Sie die übergeordnete(n) Klasse(n) als Parameter für die Klassendefinition an
|
||||
class Superhero(Human):
|
||||
|
||||
# Wenn die untergeordnete Klasse alle Definitionen des übergeordneten Elements
|
||||
# ohne Änderungen erben soll, können Sie einfach das Schlüsselwort "pass"
|
||||
# (und nichts anderes) verwenden. In diesem Fall wird jedoch auskommentiert,
|
||||
# um eine eindeutige untergeordnete Klasse zuzulassen:
|
||||
# pass
|
||||
|
||||
# Kindklassen können die Attribute ihrer Eltern überschreiben
|
||||
species = 'Superhuman'
|
||||
|
||||
# Kinder erben automatisch den Konstruktor ihrer übergeordneten Klasse
|
||||
# einschließlich ihrer Argumente, können aber auch zusätzliche Argumente oder
|
||||
# Definitionen definieren und ihre Methoden zB den Klassenkonstruktor überschreiben.
|
||||
# Dieser Konstruktor erbt das Argument "name" von der Klasse "Human" und
|
||||
# fügt die Argumente "superpowers" und "movie" hinzu:
|
||||
def __init__(self, name, movie=False,
|
||||
superpowers=["super strength", "bulletproofing"]):
|
||||
|
||||
# zusätzliche Klassenattribute hinzufügen:
|
||||
self.fictional = True
|
||||
self.movie = movie
|
||||
# Beachten Sie die veränderlichen Standardwerte, da die Standardwerte gemeinsam genutzt werden
|
||||
self.superpowers = superpowers
|
||||
|
||||
# Mit der Funktion "super" können Sie auf die Methoden der übergeordneten Klasse
|
||||
# zugreifen, die vom untergeordneten Objekt überschrieben werden,
|
||||
# in diesem Fall die Methode __init__.
|
||||
# Dies ruft den Konstruktor der übergeordneten Klasse auf:
|
||||
super().__init__(name)
|
||||
|
||||
# überschreiben der "sing" Methode
|
||||
def sing(self):
|
||||
return 'Dun, dun, DUN!'
|
||||
|
||||
# eine zusätzliche Instanzmethode hinzufügen
|
||||
def boast(self):
|
||||
for power in self.superpowers:
|
||||
print("I wield the power of {pow}!".format(pow=power))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sup = Superhero(name="Tick")
|
||||
|
||||
# Instanztypprüfungen
|
||||
if isinstance(sup, Human):
|
||||
print('I am human')
|
||||
if type(sup) is Superhero:
|
||||
print('I am a superhero')
|
||||
|
||||
# Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen, die sowohl von getattr() als auch von super() verwendet wird.
|
||||
# Dieses Attribut ist dynamisch und kann aktualisiert werden.
|
||||
print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
|
||||
# => <class 'human.Human'>, <class 'object'>)
|
||||
|
||||
# Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
|
||||
print(sup.get_species()) # => Superhuman
|
||||
|
||||
# Ruft die überschriebene Methode auf
|
||||
print(sup.sing()) # => Dun, dun, DUN!
|
||||
|
||||
# Ruft die Methode von Human auf
|
||||
sup.say('Spoon') # => Tick: Spoon
|
||||
|
||||
# Aufruf einer Methode, die nur in Superhero existiert
|
||||
sup.boast() # => I wield the power of super strength!
|
||||
# => I wield the power of bulletproofing!
|
||||
|
||||
# Vererbtes Klassenattribut
|
||||
sup.age = 31
|
||||
print(sup.age) # => 31
|
||||
|
||||
# Attribut, das nur in Superhero existiert
|
||||
print('Am I Oscar eligible? ' + str(sup.movie))
|
||||
|
||||
####################################################
|
||||
## 6.2 Multiple Inheritance
|
||||
####################################################
|
||||
|
||||
# Eine weitere Klassendefinition
|
||||
# bat.py
|
||||
|
||||
class Bat:
|
||||
|
||||
species = 'Baty'
|
||||
|
||||
def __init__(self, can_fly=True):
|
||||
self.fly = can_fly
|
||||
|
||||
# This class also has a say method
|
||||
def say(self, msg):
|
||||
msg = '... ... ...'
|
||||
return msg
|
||||
|
||||
# And its own method as well
|
||||
def sonar(self):
|
||||
return '))) ... ((('
|
||||
|
||||
if __name__ == '__main__':
|
||||
b = Bat()
|
||||
print(b.say('hello'))
|
||||
print(b.fly)
|
||||
|
||||
# Und noch eine andere Klassendefinition, die von Superhero und Bat erbt
|
||||
# superhero.py
|
||||
from superhero import Superhero
|
||||
from bat import Bat
|
||||
|
||||
# Definieren Sie Batman als eine Kindklasse, das von Superheld und Bat erbt
|
||||
class Batman(Superhero, Bat):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# In der Regel müssen Sie super aufrufen, um Attribute zu erben:
|
||||
# super (Batman, selbst) .__ init__ (* args, ** kwargs)
|
||||
# Allerdings handelt es sich hier um Mehrfachvererbung, und super()
|
||||
# funktioniert nur mit der nächsten Basisklasse in der MRO-Liste.
|
||||
# Stattdessen rufen wir explizit __init__ für alle Vorfahren auf.
|
||||
# Die Verwendung von *args und **kwargs ermöglicht die saubere Übergabe von
|
||||
# Argumenten, wobei jedes übergeordnete Element eine Schicht der Zwiebel "abschält".
|
||||
Superhero.__init__(self, 'anonymous', movie=True,
|
||||
superpowers=['Wealthy'], *args, **kwargs)
|
||||
Bat.__init__(self, *args, can_fly=False, **kwargs)
|
||||
# überschreibt den Wert für das Namensattribut
|
||||
self.name = 'Sad Affleck'
|
||||
|
||||
def sing(self):
|
||||
return 'nan nan nan nan nan batman!'
|
||||
|
||||
if __name__ == '__main__':
|
||||
sup = Batman()
|
||||
|
||||
# Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen,
|
||||
# die sowohl von getattr() als auch von super() verwendet wird.
|
||||
# Dieses Attribut ist dynamisch und kann aktualisiert werden.
|
||||
print(Batman.__mro__) # => (<class '__main__.Batman'>,
|
||||
# => <class 'superhero.Superhero'>,
|
||||
# => <class 'human.Human'>,
|
||||
# => <class 'bat.Bat'>, <class 'object'>)
|
||||
|
||||
# Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
|
||||
print(sup.get_species()) # => Superhuman
|
||||
|
||||
# Ruft die überschriebene Methode auf
|
||||
print(sup.sing()) # => nan nan nan nan nan batman!
|
||||
|
||||
# Ruft die Methode von Human auf, weil die Reihenfolge der Vererbung wichtig ist
|
||||
sup.say('I agree') # => Sad Affleck: I agree
|
||||
|
||||
# Aufrufmethode, die nur im 2. Vorfahren existiert
|
||||
print(sup.sonar()) # => ))) ... (((
|
||||
|
||||
# Vererbtes Klassenattribut
|
||||
sup.age = 100
|
||||
print(sup.age) # => 100
|
||||
|
||||
# Vererbtes Attribut vom 2. Vorfahren, dessen Standardwert überschrieben wurde.
|
||||
print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
|
||||
|
||||
|
||||
####################################################
|
||||
## 7. Fortgeschrittenes
|
||||
####################################################
|
||||
|
||||
# Generatoren helfen Ihnen, lazy Code zu erstellen.
|
||||
def double_numbers(iterable):
|
||||
for i in iterable:
|
||||
yield i + i
|
||||
|
||||
# Generatoren sind speichereffizient, da sie nur die Daten laden,
|
||||
# die zur Verarbeitung des nächsten Werts in der iterierbaren Komponente
|
||||
# erforderlich sind. Dadurch können sie ansonsten unzulässig große Wertebereiche ausführen.
|
||||
# HINWEIS: `range` ersetzt` xrange` in Python 3.
|
||||
for i in double_numbers(range(1, 900000000)): # `range` ist ein Generator.
|
||||
print(i)
|
||||
if i >= 30:
|
||||
break
|
||||
|
||||
# Genauso wie Sie ein 'list comprehension' (Listen Abstraktion) erstellen können, können Sie auch 'generator comprehension' (Generator Abstraktion) erstellen.
|
||||
values = (-x for x in [1,2,3,4,5])
|
||||
for x in values:
|
||||
print(x) # prints -1 -2 -3 -4 -5 to console/terminal
|
||||
|
||||
# Sie können eine Generator Abstraktion auch direkt in eine Liste umwandeln (casten).
|
||||
values = (-x for x in [1,2,3,4,5])
|
||||
gen_to_list = list(values)
|
||||
print(gen_to_list) # => [-1, -2, -3, -4, -5]
|
||||
|
||||
# Decorators
|
||||
# In diesem Beispiel umschliesst "beg" "say". Wenn say_please True ist, wird die zurückgegebene Nachricht geändert.
|
||||
from functools import wraps
|
||||
|
||||
def beg(target_function):
|
||||
@wraps(target_function)
|
||||
def wrapper(*args, **kwargs):
|
||||
msg, say_please = target_function(*args, **kwargs)
|
||||
if say_please:
|
||||
return "{} {}".format(msg, "Please! I am poor :(")
|
||||
return msg
|
||||
|
||||
return wrapper
|
||||
|
||||
@beg
|
||||
def say(say_please=False):
|
||||
msg = "Can you buy me a beer?"
|
||||
return msg, say_please
|
||||
|
||||
|
||||
print(say()) # Can you buy me a beer?
|
||||
print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
|
||||
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user