Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung der Python-Magiemethode

Detaillierte Erklärung der Python-Magiemethode

高洛峰
高洛峰Original
2016-10-20 09:22:141310Durchsuche

Vorbereitung

Um sicherzustellen, dass die Klasse ein neuer Typ ist, sollten Sie _metaclass_=type am Anfang Ihres Moduls einfügen.

class NewType(Object):
  mor_code_here
class OldType:
  mor_code_here


Unter diesen beiden Klassen ist NewType die neue Klasse und OldType die alte Klasse, sofern hinzugefügt front Bei _metaclass_=type gehören beide Klassen zur neuen Klasse.

Konstruktormethode

Konstruktormethode unterscheidet sich von ihrer Methode. Wenn ein Objekt erstellt wird, wird die Konstruktormethode sofort aufgerufen. Das Erstellen eines Python-Konstruktors ist sehr einfach. Konvertieren Sie einfach die Init-Methode von der einfachen Init-Methode in die magische Version der _init_-Methode.

class FooBar:
    def __init__(self):
        self.somevar = 42
          
>>> f =FooBar()
>>> f.somevar
42


Eine allgemeine Methode überschreiben

Jede Klasse kann eine oder mehrere A-Superklassen haben ( übergeordnete Klasse), die Verhaltensmethoden von der Oberklasse erbt.

class A:
    def hello(self):
        print 'hello . I am A.'
class B(A):
  pass
>>> a = A()
>>> b = B()
>>> a.hello()
hello . I am A.


Da Klasse B keine Hallo-Methode hat, erbt Klasse B Klasse A, also Klasse A wird als Hallo-Methode bezeichnet.

Die einfachste Möglichkeit, einer Unterklasse Funktionalität hinzuzufügen, ist das Hinzufügen von Methoden. Sie können aber auch einige Superklassenmethoden überschreiben, um das geerbte Verhalten anzupassen. Wie folgt:

class A:
    def hello(self):
        print 'hello . I am A.'
class B(A):
    def hello(self):
        print 'hello . I am  B'
>>> b = B()
>>> b.hello()
hello . I am  B


Spezielle und Konstruktormethoden

Überschreiben liegt im Vererbungsmechanismus An wichtige Inhalte, insbesondere für Bauweisen. Schauen Sie sich das folgende Beispiel an:

class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print 'Aaaah...'
            self.hungry = False
        else:
            print 'No, thanks!'
>>> b = Bird()
>>> b.eat()
Aaaah...
>>> b.eat()
No, thanks!


Diese Klasse definiert, dass der Vogel die Fähigkeit hat, zu fressen hat gegessen Nach einer Zeit werden Sie keinen Hunger mehr haben, was an den obigen Ausführungsergebnissen deutlich zu erkennen ist.

Dann verwenden Sie die SongBird-Klasse, um die Bird-Klasse zu erben und ihr die Gesangsmethode hinzuzufügen:

class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print 'Aaaah...'
            self.hungry = False
        else:
            print 'No, thanks!'
              
class SongBird(Bird):
         def __init__(self):
                 self.sound = 'Squawk!'
         def sing(self):
                 print self.sound
>>> s = SongBird()
>>> s.sing()
Squawk!
>>> s.eat()
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    s.eat()
  File "C:/Python27/bird", line 6, in eat
    if self.hungry:
AttributeError: &#39;SongBird&#39; object has no attribute &#39;hungry&#39;


Die Ausnahme gibt den Fehler eindeutig an: SongBird verfügt nicht über die Hungrig-Funktion. Der Grund ist folgender: In SongBird wird der Konstruktor neu geschrieben, aber der neue Konstruktor verfügt über keinen Code zum Initialisieren der hungrigen Eigenschaften. Um den gewünschten Effekt zu erzielen, muss der Konstruktor von SongBird den Konstruktor seiner Oberklasse Bird aufrufen, um die Grundinitialisierung sicherzustellen.

Zwei Methoden zur Implementierung:

1. Rufen Sie den ungebundenen Superklassenkonstruktor auf

class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print &#39;Aaaah...&#39;
            self.hungry = False
        else:
            print &#39;No, thanks!&#39;
              
class SongBird(Bird):
         def __init__(self):
                 Bird.__init__(self)
                 self.sound = &#39;Squawk!&#39;
         def sing(self):
                 print self.sound
>>> s = SongBird()
>>> s.sing()
Squawk!
>>> s.eat()
Aaaah...
>>> s.eat()
No, thanks!


Der SongBird-Klasse wurde eine Codezeile Bird.__init__(self) hinzugefügt. Wenn eine Methode für eine Instanz aufgerufen wird, wird der Parameter self der Methode automatisch an die Instanz gebunden (dies wird als gebundene Methode bezeichnet). Wenn Sie die Klassenmethode jedoch direkt aufrufen, wird keine Instanz gebunden. Dadurch können Sie die erforderlichen Selbstparameter frei bereitstellen (solche Methoden werden als ungebundene Methoden bezeichnet).

Durch die Bereitstellung der aktuellen Instanz als Selbstparameter für die ungebundene Methode kann SongBird alle Implementierungen seines Oberklassenkonstruktors verwenden, was bedeutet, dass das hungrige Attribut festgelegt werden kann.

2. Verwenden Sie die Superfunktion

__metaclass__ = type  #表明为新式类
class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print &#39;Aaaah...&#39;
            self.hungry = False
        else:
            print &#39;No, thanks!&#39;
              
class SongBird(Bird):
         def __init__(self):
                 super(SongBird,self).__init__()
                 self.sound = &#39;Squawk!&#39;
         def sing(self):
                 print self.sound
>>> s.sing()
Squawk!
>>> s.eat()
Aaaah...
>>> s.eat()
No, thanks!


Die Superfunktion kann nur in verwendet werden Klassen im neuen Stil. Die aktuelle Klasse und das aktuelle Objekt können als Parameter der Superfunktion verwendet werden. Jede Methode, die das von der Funktion zurückgegebene Objekt aufruft, ruft die Methode der Superklasse auf, nicht die aktuelle Klasse. Dann können Sie super(SongBird, self) direkt anstelle von Bird im Konstruktor von SongBird verwenden.

Attribut

Der Accessor ist eine einfache Methode, die Namen wie getHeight und setHeight verwenden kann, um einige Eigenschaften abzurufen oder erneut zu binden. Eine solche Kapselung von Zustandsvariablen ist wichtig, wenn beim Zugriff auf eine bestimmte Funktion eine Aktion ausgeführt werden muss. Wie folgt:

class Rectangle:
    def __init__(self):
        self.width = 0
        self.height = 0
    def setSize(self,size):
        self.width , self.height = size
    def getSize(self):
        return self.width , self.height
>>> r = Rectangle()
>>> r.width = 10
>>> r.height = 5
>>> r.getSize()
(10, 5)
>>> r.setSize((150,100))
>>> r.width
150


Im obigen Beispiel verwenden die Methoden getSize und setSize eine imaginäre Eigenschaft namens size. Zugriffsmethode, Größe ist ein Tupel bestehend aus Breite und Höhe.

Eigenschaftsfunktion

Die Verwendung der Eigenschaftsfunktion ist sehr einfach. Wenn Sie im vorherigen Abschnitt bereits eine Klasse wie „Rectangle“ geschrieben haben, müssen Sie nur eine Zeile hinzufügen des Codes:

__metaclass__ = type
class Rectangle:
    def __int__(self):
        self.width = 0
        self.height = 0
    def setSize(self,size):
        self.width, self.height = size
    def getSize(self):
        return self.width ,self.height
    size = property(getSize ,setSize)
>>> r = Rectangle()
>>> r.width = 10
>>> r.height = 5
>>> r.size
(10, 5)
>>> r.size = 150,100
>>> r.width
150

 


In dieser neuen Version von Retangle erstellt die Eigenschaftsfunktion eine Eigenschaft, wo die Accessor-Funktion Wird als Parameter verwendet (erst den Wert abrufen und dann den Wert zuweisen). Dieses Attribut heißt Größe. Auf diese Weise müssen Sie sich keine Gedanken mehr über die Implementierung machen und können Breite, Höhe und Größe auf die gleiche Weise handhaben.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn