Objektorientiertes Python - Bausteine

In diesem Kapitel werden wir objektorientierte Begriffe und Programmierkonzepte im Detail diskutieren. Die Klasse ist nur eine Fabrik für eine Instanz. Diese Factory enthält den Entwurf, der beschreibt, wie die Instanzen erstellt werden. Eine Instanz oder ein Objekt wird aus der Klasse erstellt. In den meisten Fällen können wir mehr als eine Instanz einer Klasse haben. Jede Instanz verfügt über eine Reihe von Attributen, und diese Attribute werden in einer Klasse definiert. Daher wird erwartet, dass jede Instanz einer bestimmten Klasse dieselben Attribute aufweist.

Klassenbündel: Verhalten und Zustand

Mit einer Klasse können Sie das Verhalten und den Status eines Objekts bündeln. Beachten Sie zum besseren Verständnis das folgende Diagramm -

Die folgenden Punkte sind bei der Erörterung von Klassenbündeln bemerkenswert -

  • Das Wort behavior ist identisch mit function - Es ist ein Code, der etwas tut (oder ein Verhalten implementiert).

  • Das Wort state ist identisch mit variables - Hier können Werte innerhalb einer Klasse gespeichert werden.

  • Wenn wir ein Klassenverhalten und einen Status zusammen behaupten, bedeutet dies, dass eine Klasse Funktionen und Variablen packt.

Klassen haben Methoden und Attribute

In Python definiert das Erstellen einer Methode ein Klassenverhalten. Die Wortmethode ist der OOP-Name, der einer Funktion gegeben wird, die innerhalb einer Klasse definiert ist. Zusammenfassend -

  • Class functions - ist ein Synonym für methods

  • Class variables - ist ein Synonym für name attributes.

  • Class - eine Blaupause für eine Instanz mit genauem Verhalten.

  • Object - Führen Sie als eine der Instanzen der Klasse die in der Klasse definierten Funktionen aus.

  • Type - gibt die Klasse an, zu der die Instanz gehört

  • Attribute - Beliebiger Objektwert: object.attribute

  • Method - ein in der Klasse definiertes "aufrufbares Attribut"

Beachten Sie zum Beispiel den folgenden Code:

var = “Hello, John”
print( type (var)) # ‘str’> or <class 'str'>
print(var.upper()) # upper() method is called, HELLO, JOHN

Schöpfung und Instanziierung

Der folgende Code zeigt, wie Sie unsere erste Klasse und dann ihre Instanz erstellen.

class MyClass(object):
   pass
# Create first instance of MyClass
this_obj = MyClass()
print(this_obj)
# Another instance of MyClass
that_obj = MyClass()
print (that_obj)

Hier haben wir eine Klasse namens erstellt MyClassund die keine Aufgabe erledigt. Das Argumentobject im MyClass Klasse beinhaltet Klassenvererbung und wird in späteren Kapiteln besprochen. pass im obigen Code zeigt an, dass dieser Block leer ist, das heißt, es ist eine leere Klassendefinition.

Lassen Sie uns eine Instanz erstellen this_obj von MyClass() Klasse und drucken Sie es wie gezeigt -

<__main__.MyClass object at 0x03B08E10>
<__main__.MyClass object at 0x0369D390>

Hier haben wir eine Instanz von erstellt MyClass.Der Hex-Code bezieht sich auf die Adresse, an der das Objekt gespeichert wird. Eine andere Instanz zeigt auf eine andere Adresse.

Definieren wir nun eine Variable innerhalb der Klasse MyClass() und holen Sie sich die Variable aus der Instanz dieser Klasse, wie im folgenden Code gezeigt -

class MyClass(object):
   var = 9

# Create first instance of MyClass
this_obj = MyClass()
print(this_obj.var)

# Another instance of MyClass

that_obj = MyClass()
print (that_obj.var)

Ausgabe

Sie können die folgende Ausgabe beobachten, wenn Sie den oben angegebenen Code ausführen -

9
9

Da die Instanz weiß, von welcher Klasse sie instanziiert wird, sucht die Instanz bei der Anforderung eines Attributs von einer Instanz nach dem Attribut und der Klasse. Dies nennt man dasattribute lookup.

Instanzmethoden

Eine in einer Klasse definierte Funktion heißt a method.Eine Instanzmethode benötigt eine Instanz, um sie aufzurufen, und benötigt keinen Dekorator. Beim Erstellen einer Instanzmethode ist der erste Parameter immerself. Obwohl wir es (self) bei jedem anderen Namen nennen können, wird empfohlen, self zu verwenden, da es sich um eine Namenskonvention handelt.

class MyClass(object):
   var = 9
   def firstM(self):
      print("hello, World")
obj = MyClass()
print(obj.var)
obj.firstM()

Ausgabe

Sie können die folgende Ausgabe beobachten, wenn Sie den oben angegebenen Code ausführen -

9
hello, World

Beachten Sie, dass wir im obigen Programm eine Methode mit self als Argument definiert haben. Wir können die Methode jedoch nicht aufrufen, da wir kein Argument dafür deklariert haben.

class MyClass(object):
   def firstM(self):
      print("hello, World")
      print(self)
obj = MyClass()
obj.firstM()
print(obj)

Ausgabe

Sie können die folgende Ausgabe beobachten, wenn Sie den oben angegebenen Code ausführen -

hello, World
<__main__.MyClass object at 0x036A8E10>
<__main__.MyClass object at 0x036A8E10>

Verkapselung

Die Kapselung ist eine der Grundlagen von OOP. OOP ermöglicht es uns, die Komplexität der internen Arbeitsweise des Objekts, die für den Entwickler von Vorteil ist, auf folgende Weise zu verbergen:

  • Vereinfacht und erleichtert das Verstehen der Verwendung eines Objekts, ohne die Interna zu kennen.

  • Jede Änderung kann leicht verwaltet werden.

Die objektorientierte Programmierung hängt stark von der Kapselung ab. Die Begriffe Kapselung und Abstraktion (auch als Datenverstecken bezeichnet) werden häufig als Synonyme verwendet. Sie sind fast synonym, da die Abstraktion durch Einkapselung erreicht wird.

Die Kapselung bietet uns den Mechanismus, den Zugriff auf einige der Objektkomponenten einzuschränken. Dies bedeutet, dass die interne Darstellung eines Objekts nicht von außerhalb der Objektdefinition gesehen werden kann. Der Zugriff auf diese Daten erfolgt normalerweise über spezielle Methoden -Getters und Setters.

Diese Daten werden in Instanzattributen gespeichert und können von überall außerhalb der Klasse bearbeitet werden. Um dies zu sichern, sollte auf diese Daten nur mit Instanzmethoden zugegriffen werden. Direkter Zugriff sollte nicht gestattet sein.

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age

zack = MyClass()
zack.setAge(45)
print(zack.getAge())

zack.setAge("Fourty Five")
print(zack.getAge())

Ausgabe

Sie können die folgende Ausgabe beobachten, wenn Sie den oben angegebenen Code ausführen -

45
Fourty Five

Die Daten sollten nur unter Verwendung von Ausnahmebehandlungskonstrukten gespeichert werden, wenn sie korrekt und gültig sind. Wie wir oben sehen können, gibt es keine Einschränkung für die Benutzereingabe der setAge () -Methode. Es kann sich um eine Zeichenfolge, eine Zahl oder eine Liste handeln. Wir müssen also den obigen Code überprüfen, um sicherzustellen, dass er korrekt gespeichert wird.

class MyClass(object):
   def setAge(self, num):
      self.age = num

   def getAge(self):
      return self.age
zack = MyClass()
zack.setAge(45)
print(zack.getAge())
zack.setAge("Fourty Five")
print(zack.getAge())

Init Konstruktor

Das __initDie Methode __ wird implizit aufgerufen, sobald ein Objekt einer Klasse instanziiert wird. Dadurch wird das Objekt initialisiert.

x = MyClass()

Die oben gezeigte Codezeile erstellt eine neue Instanz und weist dieses Objekt der lokalen Variablen x zu.

Das heißt, die Instanziierungsoperation calling a class object, erstellt ein leeres Objekt. Viele Klassen erstellen gerne Objekte mit Instanzen, die an einen bestimmten Anfangszustand angepasst sind. Daher kann eine Klasse eine spezielle Methode mit dem Namen '__init __ ()' wie gezeigt definieren -

def __init__(self):
   self.data = []

Python ruft während der Instanziierung __init__ auf, um ein zusätzliches Attribut zu definieren, das auftreten soll, wenn eine Klasse instanziiert wird, die möglicherweise einige Anfangswerte für dieses Objekt einrichtet oder eine für die Instanziierung erforderliche Routine ausführt. In diesem Beispiel kann eine neue, initialisierte Instanz erhalten werden durch -

x = MyClass()

Die Methode __init __ () kann für eine größere Flexibilität einzelne oder mehrere Argumente enthalten. Der Init steht für Initialisierung, da er Attribute der Instanz initialisiert. Es wird der Konstruktor einer Klasse genannt.

class myclass(object):
   def __init__(self,aaa, bbb):
      self.a = aaa
      self.b = bbb

x = myclass(4.5, 3)
print(x.a, x.b)

Ausgabe

4.5 3

Klassenattribute

Das in der Klasse definierte Attribut heißt "Klassenattribute" und die in der Funktion definierten Attribute heißen "Instanzattribute". Während der Definition wird diesen Attributen kein Selbst vorangestellt, da dies die Eigenschaft der Klasse und nicht einer bestimmten Instanz ist.

Auf die Klassenattribute kann sowohl von der Klasse selbst (className.attributeName) als auch von den Instanzen der Klasse (inst.attributeName) zugegriffen werden. Die Instanzen haben also Zugriff sowohl auf das Instanzattribut als auch auf Klassenattribute.

>>> class myclass():
   age = 21
>>> myclass.age
21
>>> x = myclass()
>>> x.age
21
>>>

Ein Klassenattribut kann in einer Instanz überschrieben werden, obwohl dies keine gute Methode ist, um die Kapselung zu unterbrechen.

In Python gibt es einen Suchpfad für Attribute. Die erste ist die in der Klasse definierte Methode und dann die darüber liegende Klasse.

>>> class myclass(object):
   classy = 'class value'
>>> dd = myclass()
>>> print (dd.classy) # This should return the string 'class value'
class value
>>>
>>> dd.classy = "Instance Value"
>>> print(dd.classy) # Return the string "Instance Value"
Instance Value
>>>
>>> # This will delete the value set for 'dd.classy' in the instance.
>>> del dd.classy
>>> >>> # Since the overriding attribute was deleted, this will print 'class
value'.

>>> print(dd.classy)
class value
>>>

Wir überschreiben das Klassenattribut 'classy' in der Instanz dd. Wenn es überschrieben wird, liest der Python-Interpreter den überschriebenen Wert. Sobald der neue Wert mit 'del' gelöscht wurde, ist der überschriebene Wert in der Instanz nicht mehr vorhanden, und daher geht die Suche eine Ebene höher und ruft ihn von der Klasse ab.

Arbeiten mit Klassen- und Instanzdaten

Lassen Sie uns in diesem Abschnitt verstehen, wie sich die Klassendaten auf die Instanzdaten beziehen. Wir können Daten entweder in einer Klasse oder in einer Instanz speichern. Wenn wir eine Klasse entwerfen, entscheiden wir, welche Daten zur Instanz gehören und welche Daten in der Gesamtklasse gespeichert werden sollen.

Eine Instanz kann auf die Klassendaten zugreifen. Wenn wir mehrere Instanzen erstellen, können diese Instanzen auf ihre einzelnen Attributwerte sowie auf die gesamten Klassendaten zugreifen.

Somit sind Klassendaten die Daten, die von allen Instanzen gemeinsam genutzt werden. Beachten Sie den unten angegebenen Code, um das Verständnis zu verbessern -

class InstanceCounter(object):
   count = 0 # class attribute, will be accessible to all instances
   def __init__(self, val):
      self.val = val
      InstanceCounter.count +=1 # Increment the value of class attribute, accessible through class name
# In above line, class ('InstanceCounter') act as an object
   def set_val(self, newval):
      self.val = newval

   def get_val(self):
      return self.val

   def get_count(self):
      return InstanceCounter.count
a = InstanceCounter(9)
b = InstanceCounter(18)
c = InstanceCounter(27)

for obj in (a, b, c):
   print ('val of obj: %s' %(obj.get_val())) # Initialized value ( 9, 18, 27)
   print ('count: %s' %(obj.get_count())) # always 3

Ausgabe

val of obj: 9
count: 3
val of obj: 18
count: 3
val of obj: 27
count: 3

Kurz gesagt, Klassenattribute sind für alle Instanzen der Klasse gleich, während Instanzattribute für jede Instanz spezifisch sind. Für zwei verschiedene Instanzen haben wir zwei verschiedene Instanzattribute.

class myClass:
   class_attribute = 99

   def class_method(self):
      self.instance_attribute = 'I am instance attribute'

print (myClass.__dict__)

Ausgabe

Sie können die folgende Ausgabe beobachten, wenn Sie den oben angegebenen Code ausführen -

{'__module__': '__main__', 'class_attribute': 99, 'class_method': 
      
       , '__dict__': 
       
        , '__weakref__': 
        
         , '__doc__': None} 
        
       
      

The instance attribute myClass.__dict__ as shown −

>>> a = myClass()
>>> a.class_method()
>>> print(a.__dict__)
{'instance_attribute': 'I am instance attribute'}