970 Stimmen

Was bewirken __init__ und self in Python?

Ich lerne gerade die Programmiersprache Python und bin auf etwas gestoßen, das ich nicht ganz verstehe.

Mit einer Methode wie:

def method(self, blah):
    def __init__(?):
        ....
    ....

Was bedeutet self tun? Was soll sie sein? Ist sie obligatorisch?

Was bedeutet die __init__ Methode tun? Warum ist sie notwendig? (usw.)

Ich denke, dass es sich um OOP-Konstrukte handeln könnte, aber ich weiß nicht sehr viel.

705voto

Chris B. Punkte 78022

In diesem Code:

class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

... die self steht für die Instanz des Objekts selbst. Die meisten objektorientierten Sprachen übergeben diese Variable als versteckten Parameter an die für ein Objekt definierten Methoden; Python tut dies nicht. Sie müssen sie explizit deklarieren. Wenn Sie eine Instanz des A Klasse und rufen ihre Methoden auf, wird sie automatisch übergeben, wie in ...

a = A()               # We do not pass any argument to the __init__ method
a.method_a('Sailor!') # We only pass a single argument

Le site __init__ Methode ist ungefähr das, was in Python einen Konstruktor darstellt. Wenn Sie die Methode A() Python erstellt ein Objekt für Sie und übergibt es als ersten Parameter an die Funktion __init__ Methode. Alle zusätzlichen Parameter (z.B., A(24, 'Hello') ) werden ebenfalls als Argumente übergeben - in diesem Fall wird eine Ausnahme ausgelöst, da der Konstruktor sie nicht erwartet.

17 Stimmen

Was wäre, wenn Sie die x = 'Hello' außerhalb init aber innerhalb der Klasse? ist es wie Java, wo es das gleiche ist, oder wird es wie eine statische Variable, die nur einmal initialisiert wird?

23 Stimmen

Sie ist wie eine statische Variable. Sie wird nur einmal initialisiert und ist verfügbar durch A.x o a.x . Beachten Sie, dass das Überschreiben dieser Funktion in einer bestimmten Klasse keine Auswirkungen auf die Basis hat, also A.x = 'foo'; a.x = 'bar'; print a.x; print A.x wird gedruckt bar dann foo

187 Stimmen

Es ist erwähnenswert, dass das erste Argument nicht unbedingt heißen muss self Es ist einfach eine Konvention.

314voto

RedBlueThing Punkte 40761

Ja, Sie haben Recht, das sind Oop-Konstrukte.

__init__ ist der Konstruktor für eine Klasse. Die self Parameter bezieht sich auf die Instanz des Objekts (wie this in C++).

class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y

Le site __init__ Methode wird aufgerufen, nachdem der Speicher für das Objekt zugewiesen wurde:

x = Point(1,2)

Es ist wichtig, die self Parameter innerhalb einer Objektmethode, wenn Sie den Wert mit dem Objekt beibehalten wollen. Wenn Sie zum Beispiel die Methode __init__ Methode wie folgt:

class Point:
    def __init__(self, x, y):
        _x = x
        _y = y

Ihr x y y Parameter würden in Variablen auf dem Stack gespeichert und verworfen werden, wenn die init-Methode den Anwendungsbereich verlässt. Das Setzen dieser Variablen als self._x y self._y setzt diese Variablen als Mitglieder der Point Objekts (zugänglich während der Lebensdauer des Objekts).

N.B. Einige Klarstellungen zur Verwendung des Wortes "Konstruktor" in dieser Antwort. Technisch gesehen sind die Aufgaben eines "Konstruktors" in Python auf zwei Methoden aufgeteilt. Diese Methoden sind __new__ (zuständig für die Zuweisung von Speicher) und __init__ (wie hier beschrieben, zuständig für die Initialisierung der neu erstellten Instanz).

5 Stimmen

Gibt es also einen Grund, warum Sie nicht wollen, dass self im Konstruktor sein? Warum müssen Sie es überhaupt angeben? Wäre es nicht besser, wenn es implizit wäre?

4 Stimmen

Soweit ich weiß, ist __ init __ kein Konstruktor, es ist die erste Methode, die ausgeführt wird, wenn ein Objekt erstellt wird, __ init __ wird zur Einrichtung des Objekts verwendet. __ new __ ist der Konstruktor in Python.

1 Stimmen

Für diejenigen, die diese Antwort lesen, ist sie völlig falsch. __init__ keinen Platz im Speicher zuweist. Es wird erwartet, dass die Instanzattribute initialisiert werden. Was im Speicher zugewiesen wird, ist __new__ .

283voto

Dave Everitt Punkte 15928

Ein kurzes anschauliches Beispiel

In der Hoffnung, dass es ein wenig hilft, hier ein einfaches Beispiel, das ich benutzt habe, um den Unterschied zwischen einer Variablen, die innerhalb einer Klasse deklariert ist, und einer Variablen, die innerhalb einer __init__ Funktion:

class MyClass(object):
    i = 123
    def __init__(self):
        self.i = 345

a = MyClass()
print(a.i)
print(MyClass.i)

Ausgabe:

345
123

7 Stimmen

Interessante Beobachtung, aber ich glaube, Sie sind auf dem falschen Weg. Mit print MyClass.i sieht es eher so aus, als ob Sie eine 'statische' Variable i aufrufen, während Sie mit a.i eine Member-Variable, i, aufrufen. init ist lediglich ein Konstruktor, der zuerst ausgeführt wird, wenn Sie ein Objekt der Klasse erstellen.

56 Stimmen

Das ist es, was ich mir mit diesem Beispiel 'erklären' wollte - dass die Variable, die durch __init__ ist das, was übergeben wird an Instanzen der Klasse, nicht die 'statische' Variable der Klasse selbst, die denselben Namen hat...

1 Stimmen

Ich finde es bemerkenswert, dass das erste i (i=123), das Sie erstellen, eine Objektvariable ist, während das zweite i (self.i = 345) eine Instanzvariable ist. Während Instanzvariablen für jede Instanz der Klasse unterschiedliche Werte haben können, sind die Klassenvariablen für alle Instanzen, die von dieser Klasse erstellt werden, gleich. (Natürlich kann man die Klassenvariablen auch innerhalb des Codes ändern). Die korrekte Bezeichnung für "statische" Variablen ist also Objektvariable, und Instanzvariablen werden innerhalb einer Klassenmethode deklariert (in diesem Fall die init Methode, kann aber natürlich auch eine andere Methode sein).

49voto

Kurz gesagt:

  1. self bezieht sich, wie der Name schon sagt, auf selbst - das Objekt, das die Methode aufgerufen hat. Das heißt, wenn Sie N Objekte haben, die die Methode aufrufen, dann self.a verweist für jedes der N Objekte auf eine eigene Instanz der Variablen. Stellen Sie sich N Kopien der Variablen a für jedes Objekt
  2. __init__ ist das, was in anderen OOP-Sprachen wie C++/Java als Konstruktor bezeichnet wird. Die Grundidee ist, dass es sich um eine Spezial Methode, die automatisch aufgerufen wird, wenn ein Objekt dieser Klasse erstellt wird

40voto

Hrvoje Punkte 9859

Objekte der Klasse unterstützen zwei Arten von Operationen: Attributreferenzen und Instanziierung

Attribut-Referenzen verwenden Sie die Standardsyntax, die für alle Attributreferenzen in Python verwendet wird: obj.name. Gültige Attributnamen sind alle Namen, die sich im Namensraum der Klasse befanden, als das Klassenobjekt erstellt wurde. Wenn die Klassendefinition also wie folgt aussähe:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

dann MyClass.i y MyClass.f sind gültige Attributreferenzen, die eine ganze Zahl bzw. ein Funktionsobjekt zurückgeben. Klassenattribute können auch zugewiesen werden, so können Sie den Wert von MyClass.i durch Zuweisung. __doc__ ist ebenfalls ein gültiges Attribut, das den zur Klasse gehörenden Docstring zurückgibt: "Eine einfache Beispielklasse".

Instanziierung von Klassen verwendet die Funktionsschreibweise. Tun Sie einfach so, als sei das Klassenobjekt eine parameterlose Funktion, die eine neue Instanz der Klasse zurückgibt. Zum Beispiel:

x = MyClass()

Le site Instanziierung Operation ("Aufruf" eines Klassenobjekts) erzeugt ein leeres Objekt. Viele Klassen möchten Objekte erzeugen, deren Instanzen an einen bestimmten Anfangszustand angepasst sind. Daher kann eine Klasse eine spezielle Methode namens __init__() etwa so:

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

Wenn eine Klasse eine __init__() Methode wird bei der Instanziierung der Klasse automatisch __init__() für die neu erstellte Klasseninstanz. In diesem Beispiel kann also eine neue, initialisierte Instanz erhalten werden durch:

x = MyClass()

Natürlich ist die __init__() Methode kann Argumente für mehr Flexibilität enthalten. In diesem Fall werden die Argumente, die dem Klasseninstanziierungsoperator übergeben werden, an __init__() . Zum Beispiel,

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i

Entnommen aus dem offiziellen Dokumentation was mir letztendlich am meisten geholfen hat.


Hier ist mein Beispiel

class Bill():
    def __init__(self,apples,figs,dates):
        self.apples = apples
        self.figs = figs
        self.dates = dates
        self.bill = apples + figs + dates
        print ("Buy",self.apples,"apples", self.figs,"figs 
                and",self.dates,"dates. 
                Total fruitty bill is",self.bill," pieces of fruit :)")

Wenn Sie eine Instanz der Klasse Bill erstellen:

purchase = Bill(5,6,7)

Sie erhalten:

> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18  pieces of
> fruit :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X