Objektorientierte Programmierung
Objektorientierte Programmierung (OOP) in Python
- Alles in Python ist ein Objekt
- Zeigt Datentypen nach Klassentyp an
print(type(None)) # <class 'NoneType'>
print(type(True)) # <class 'bool'>
print(type(5)) # <class 'int'>
print(type(5.5)) # <class 'float'>
print(type('hello')) # <class 'str'>
print(type([])) # <class 'list'>
print(type(())) # <class 'tuple'>
print(type({})) # <class 'dict'>
- Jeder in Python integrierte Datentyp ist eigentlich eine Klasse.
- Wenn Sie einen Wert erstellen, instanziieren Sie ein Objekt dieser Klasse.
- Beispiel: 5 ist ein Objekt der Klasse int, 'hello' ist ein Objekt der Klasse str.
Erstellen Sie Ihre eigenen Klassen
- Wir sind in der Lage, unsere eigenen Typen, unsere eigenen Datentypen mit unterschiedlichen Attributen und Methoden zu erstellen.
- Wir können unsere eigenen Klassen und Objekte erstellen.
- OOP ist ein Programmierparadigma, das „Objekte“ zur Darstellung von Daten und Methoden zur Manipulation dieser Daten verwendet.
- Eine Klasse ist eine Blaupause zum Erstellen von Objekten. Es definiert eine Reihe von Attributen und Methoden.
- Ein Objekt ist eine Instanz einer Klasse. Es wird auf der Grundlage der von der Klasse bereitgestellten Blaupause erstellt und verfügt über einen eigenen, einzigartigen Zustand und ein eigenes Verhalten.
class BigObj: # Blueprint (class name should be in PascalCase, singular)
pass
obj1 = BigObj() # () Instantiate or create an object
print(type(obj1)) # shows that BigObj is a class
- So möchten Sie Ihren Code organisieren.
- Denken Sie weniger prozedural und mehr in Bezug auf die Funktionalität
- Immer wenn wir eine Methode erstellen, ist der Parameter self erforderlich self bezieht sich auf alles, was sich links vom Punkt befindet.
class PlayerCharacter: #class object attribute, it's not dynamic, it's static
membership = True
#Constructor or # Initialization or init method(dunder method)
def __init__(self, name='anonymous', age=0):
#Can access class object attribute through self, can add safeguards and controls
if age > 18:
self.name = name
self.age = age
def run(self):
print('run')
return 'done'
def shout(self):
print(f'my name is {self.name}')
@classmethod
- Es geht darum, eine Methode zu definieren, die an die Klasse und nicht an das Objekt der Klasse gebunden ist.
- Es ist eine Methode für eine tatsächliche Klasse – Alternativer Konstruktor, der Objekte auf unterschiedliche Weise erstellen kann
@classmethod
def add_things(cls, num1, num2):
return cls('Teddy', num1 + num2)
@staticmethod
– Es handelt sich um eine Methode, die weder eine Instanz bearbeitet noch den Klassenstatus ändert. – Sie verhält sich wie eine reguläre Funktion, gehört aber zum Namensraum der Klasse.
@staticmethod
def add_numbers(num1, num2):
return num1 + num2
init-Methode
– Dadurch wird die init-Methode oder der Objektkonstruktor aufgerufen
player1 = PlayerCharacter('Cindy', 20)
player1.attack = 50 # can add new attributes to the object after its been created
# can create different players with different attributes
print(player1) # Output: <__main__.PlayerCharacter object at 0x7f9c8c4d1d60>
print(player1.name) # Output: Cindy(access by .name)
print(player1.age)
player1.run() # Output: run
print(help(player1)) # shows blueprint of the object
player1.shout() # Output: my name is Cindy
player2 = PlayerCharacter.add_things(12, 10)
print(player2.age)
Ein weiteres Beispiel: Katzenklasse
class Cat:
def __init__(self, name, color):
self.name = name
self.color = color
def meow(self):
print(f'{self.name} says meow!')
cat1 = Cat('Whiskers', 'black')
print(cat1.name) # Output: Whiskers
print(cat1.color) # Output: black
cat1.meow() # Output: Whiskers says meow!
Syntax von OOP
class NameOfClass:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def method(self):
code
pass
@classmethod
def class_method(cls, param1, param2):
code
pass
@staticmethod
def static_method(param1, param2):
code
pass
4 Säulen von OOP
1. Kapselung:
- Es ist die Bindung von Daten und Funktionen, die diese Daten manipulieren und die wir in einem großen Objekt kapseln{OOP}
- Es schützt Methoden, Funktionen und alle anderen Dinge vor Eingriffen und Missbrauch von außen.
2. Abstraktion:
- Es ist das Konzept, die komplexe Realität zu verbergen und gleichzeitig nur die notwendigen Teile offenzulegen.
- Die Idee hinter der Abstraktion besteht darin, dass wir Informationen verbergen und nur Zugriff auf Dinge gewähren, die einem Benutzer am Herzen liegen. _name: geschütztes Attribut, Unterstrich bedeutet, dass Sie dies nicht berühren sollten __Name: privates Attribut, doppelter Unterstrich bedeutet, dass Sie dies wirklich nicht anfassen sollten
3. Vererbung:
- Es ist eine Möglichkeit, neue Klassen aus bereits definierten Klassen zu bilden. In Python ist alles ein Objekt und alle Objekte erben von einer Basisobjektklasse.
Beispiel für Vererbung:
class User(object): # parent class or base class or super class
- Das Objekt ist die standardmäßige übergeordnete Klasse in Python und verfügt über integrierte Dunder-Methoden
- Python erbt von der Basisobjektklasse, die Python bereitstellt Wir benötigen keine Init-Methode, wenn keine Variablen oder Attribute zugewiesen werden sollen
def __init__(self, email):
self.email = email
def sign_in(self): # chilren classes, subclasses, or derived classes
print('logged in')
class Wizard(User): # Wizard class inherits User class by passing it as parameter
def __init__(self, name, power, email):
super().__init__(email) # calling the parent class constructor
self.name = name
self.power = power
def attack(self):
print(f'attacking with power of {self.power}')
class Archer(User):
def __init__(self, name, num_arrows):
self.name = name
self.num_arrows = num_arrows
def attack(self):
print(f'attacking with arrows: arrows left - {self.num_arrows}')
def run(self):
print('ran really fast')
wizard1 = Wizard('Merlin', 50, 'merlin@gmail.com')
archer1 = Archer('Robin', 100)
wizard1.attack() # Output: attacking with power of 50
archer1.attack() # Output: attacking with arrows: arrows left - 100
wizard1.sign_in() # Output: logged in # inherited method from User class
print(wizard1.email) # inherited attribute from User class
ist eine Instanz
Überprüfen Sie, ob etwas eine Instanz oder ein Objekt einer Klasse ist - syntax = isinstance(instance, ClassName) # gibt True oder False zurück
print(isinstance(wizard1, Wizard)) # Output: True
print(isinstance(wizard1, User)) # Output: True
print(isinstance(wizard1, object)) # Output: True(all classes inherit from object class)
Mehrfachvererbung
Dies bedeutet, dass eine Klasse von mehr als einer Basisklasse abgeleitet werden kann.
class HybridBorg(Wizard, Archer): # can give multiple parameters
def __init__(self, name, arrows):
Archer.__init__(self, name, arrows)
hb1 = HybridBorg('borgie', 100)
print(hb1.sign_in())
print(hb1.num_arrows)
print(hb1.run())
4. Polymorphismus:
- bedeutet, viele Formen zu haben.
- Gleicher Methodenname, unterschiedliches Verhalten je nach Objekt.
print(wizard1.attack())
print(archer1.attack())
Sie haben dieselben Methodennamen, aber das aufrufende Objekt ist unterschiedlich
Beispiel für Polymorphismus:
def player_attack(char):
char.attack()
player_attack(wizard1)
player_attack(archer1)
for char in [wizard1, archer1]:
char.attack()
Selbstbeobachtung
Introspektion in der Computerprogrammierung bedeutet die Fähigkeit, den Typ eines Objekts zur Laufzeit zu bestimmen.(zeigt, worauf Sie Zugriff haben)
print(dir(wizard1)) # shows all attributes and methods of the object
Dunder-Methode (Methode mit doppeltem Unterstrich) / Magic-Methode
Dunder-Methoden sind spezielle Methoden in Python, die mit doppelten Unterstrichen beginnen und enden (z. B. str, len). – Wird zum Anpassen des Objektverhaltens verwendet.
class Toy():
def __init__(self, color, age):
self.color = color
self.age = age
self.my_dict = {'name': 'Yoyo', 'has_toys': True}
Die Methode str wird nur geändert, wenn wir sie für dieses bestimmte Objekt verwenden.
def __str__(self):
return f'{self.color}'
() oder die Methode call ermöglicht Aufruffunktionen, die diesen Dunder-Aufruf verwenden.
def __call__(self):
return 'yes?'
def __len__(self):
return 5
def __getitem__(self, i):
return self.my_dict[i]
def __del__(self):
print('deleted!')
action_figure = Toy('red', 0)
print(action_figure.__str__()) # default dunder method that returns a string representation
print(str(action_figure)) # same as above
print(len(action_figure)) # Output: 5
print(action_figure()) # Output: yes?
print(action_figure['name']) # Output: Yoyo
del action_figure # Output: deleted!
Method Resolution Order (MRO)
– Definiert die Reihenfolge, in der Python in Vererbungshierarchien nach Methoden sucht.
– Regel, die Python befolgt, um zu bestimmen, wann Sie eine Methode mit komplizierter Vererbungsstruktur ausführen.
class A:
num = 10
class B(A):
pass
class C(A):
num = 1
class D(B, C):
pass
print(D.num) # Output: 1
Python sucht nach num in D, dann B, dann C, dann A. Zuerst findet es num in C.
print(D.mro()) # shows the method resolution order
print(D.__mro__) # same as above
D.__str__ # shows the dunder methods available for class D
Erkunden Sie verschiedene Anwendungsfälle von MRO:
Anwendungsfall von MRO