Ich habe Probleme, die Initialisierung von Klassen zu verstehen.
Was ist der Sinn von ihnen und woher wissen wir, was wir in sie aufnehmen sollen? Erfordert das Schreiben in Klassen eine andere Art des Denkens als das Erstellen von Funktionen (ich dachte, ich könnte einfach Funktionen erstellen und sie dann einfach in eine Klasse einschließen, damit ich sie wiederverwenden kann. Funktioniert das?)
Hier ist ein Beispiel:
class crawler:
# Initialize the crawler with the name of database
def __init__(self,dbname):
self.con=sqlite.connect(dbname)
def __del__(self):
self.con.close()
def dbcommit(self):
self.con.commit()
Oder ein anderes Codebeispiel:
class bicluster:
def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
self.left=left
self.right=right
self.vec=vec
self.id=id
self.distance=distance
Es gibt so viele Klassen, auf die __init__
ich stoße, wenn ich versuche, den Code anderer Leute zu lesen, aber ich verstehe die Logik beim Erstellen nicht.
Antworten:
Nach dem, was Sie geschrieben haben, fehlt Ihnen ein kritisches Stück Verständnis: der Unterschied zwischen einer Klasse und einem Objekt.
__init__
initialisiert keine Klasse, sondern eine Instanz einer Klasse oder eines Objekts. Jeder Hund hat Farbe, Hunde als Klasse jedoch nicht. Jeder Hund hat vier oder weniger Füße, die Klasse der Hunde jedoch nicht. Die Klasse ist ein Konzept eines Objekts. Wenn Sie Fido und Spot sehen, erkennen Sie ihre Ähnlichkeit, ihre Doghood. Das ist die Klasse.Wenn du sagst
Du sagst, Fido ist ein brauner Hund mit 4 Beinen, während Spot ein bisschen verkrüppelt und meistens gelb ist. Die
__init__
Funktion wird als Konstruktor oder Initialisierer bezeichnet und automatisch aufgerufen, wenn Sie eine neue Instanz einer Klasse erstellen. Innerhalb dieser Funktion wird das neu erstellte Objekt dem Parameter zugewiesenself
. Die Notationself.legs
ist ein Attribut, daslegs
vom Objekt in der Variablen aufgerufen wirdself
. Attribute ähneln Variablen, beschreiben jedoch den Status eines Objekts oder bestimmte Aktionen (Funktionen), die dem Objekt zur Verfügung stehen.colour
Beachten Sie jedoch, dass Sie sich nicht auf die Doghood selbst einstellen - es ist ein abstraktes Konzept. Es gibt Attribute, die für Klassen sinnvoll sind. Ist zum Beispielpopulation_size
eine solche - es macht keinen Sinn, den Fido zu zählen, weil Fido immer einer ist. Es ist sinnvoll, Hunde zu zählen. Nehmen wir an, es gibt 200 Millionen Hunde auf der Welt. Es ist Eigentum der Hundeklasse. Fido hat nichts mit der Zahl von 200 Millionen zu tun, Spot auch nicht. Es wird als "Klassenattribut" bezeichnet, im Gegensatz zu "Instanzattributen", diecolour
oderlegs
höher sind.Nun zu etwas weniger Eckzahnigem und mehr Programmierbezogenem. Wie ich weiter unten schreibe, ist eine Klasse zum Hinzufügen von Dingen nicht sinnvoll - wovon ist eine Klasse? Klassen in Python bestehen aus Sammlungen verschiedener Daten, die sich ähnlich verhalten. Die Klasse der Hunde besteht aus Fido und Spot und 199999999998 ähnlichen Tieren, die alle auf Laternenpfählen pinkeln. Woraus besteht die Klasse zum Hinzufügen von Dingen? Durch welche ihnen innewohnenden Daten unterscheiden sie sich? Und welche Aktionen teilen sie?
Zahlen ... das sind jedoch interessantere Themen. Sagen wir, Ganzzahlen. Es gibt viele von ihnen, viel mehr als Hunde. Ich weiß, dass Python bereits Ganzzahlen hat, aber lasst uns dumm spielen und sie erneut "implementieren" (indem wir betrügen und Pythons Ganzzahlen verwenden).
Ganzzahlen sind also eine Klasse. Sie haben einige Daten (Wert) und einige Verhaltensweisen ("füge mich zu dieser anderen Zahl hinzu"). Lassen Sie uns dies zeigen:
Dies ist etwas fragil (wir gehen davon aus, dass
other
es sich um eine MyInteger handelt), aber wir werden sie jetzt ignorieren. In echtem Code würden wir nicht; Wir würden es testen, um sicherzugehen und es vielleicht sogar zu erzwingen ("Sie sind keine ganze Zahl? Sie haben 10 Nanosekunden Zeit, um eins zu werden! 9 ... 8 ...")Wir könnten sogar Brüche definieren. Brüche wissen auch, wie sie sich selbst hinzufügen können.
Es gibt sogar mehr Brüche als ganze Zahlen (nicht wirklich, aber Computer wissen das nicht). Machen wir zwei:
Sie erklären hier eigentlich nichts. Attribute sind wie eine neue Art von Variablen. Normale Variablen haben nur einen Wert. Sagen wir, Sie schreiben
colour = "grey"
. Sie können nicht eine andere Variable mit dem Namen haben ,colour
das ist"fuchsia"
- nicht an der gleichen Stelle im Code.Arrays lösen das bis zu einem gewissen Grad. Wenn Sie sagen
colour = ["grey", "fuchsia"]
, Sie haben zwei Farben in die Variable gestapelt, aber Sie unterscheiden sie durch ihre Position (in diesem Fall 0 oder 1).Attribute sind Variablen, die an ein Objekt gebunden sind. Wie bei Arrays können wir bei verschiedenen Hunden viele
colour
Variablen haben . Ist also eine Variable, aber eine andere. Der erste ist an das Objekt innerhalb der Variablen gebunden ; der zweite , . Wenn Sie jetzt oder aufrufen , wird immer ein unsichtbarer Parameter angezeigt, der dem baumelnden zusätzlichen Parameter am Anfang der Parameterliste zugewiesen wird. Es wird herkömmlicherweise aufgerufen und erhält den Wert des Objekts vor dem Punkt. So wird innerhalb des Hundes (Konstrukteurs) sein, was auch immer der neue Hund sein wird; innerhalb ‚s , wird auf das Objekt in den Variablen gebunden werden . So,fido.colour
spot.colour
fido
spot
Dog(4, "brown")
three.add(five)
self
__init__
self
MyInteger
add
self
three
three.value
wird die gleiche Variable außerhalb deradd
, wieself.value
innerhalb deradd
.Wenn ich sage
the_mangy_one = fido
, beziehe ich mich auf das Objektfido
mit einem anderen Namen. Von nun anfido.colour
ist genau die gleiche Variable wiethe_mangy_one.colour
.Also, die Dinge in der
__init__
. Sie können sich vorstellen, dass sie Dinge in der Geburtsurkunde des Hundes vermerken.colour
an sich ist eine zufällige Variable, könnte alles enthalten.fido.colour
oderself.colour
ist wie ein Formularfeld auf dem Ausweis des Hundes; und__init__
füllt der Angestellte es zum ersten Mal aus.Noch klarer?
BEARBEITEN : Erweitern Sie den Kommentar unten:
Du meinst eine Liste von Objekten , nicht wahr?
Erstens
fido
ist eigentlich kein Objekt. Es ist eine Variable, die derzeit ein Objekt enthält, genau wie wenn Sie sagenx = 5
,x
eine Variable, die derzeit die Nummer fünf enthält. Wenn Sie später Ihre Meinung ändern, können Sie dies tunfido = Cat(4, "pleasing")
(solange Sie eine Klasse erstellt habenCat
) undfido
würden fortan ein Katzenobjekt "enthalten". Wenn Sie dies tunfido = x
, enthält es die Nummer fünf und überhaupt kein Tierobjekt.Eine Klasse selbst kennt ihre Instanzen nur, wenn Sie speziell Code schreiben, um sie zu verfolgen. Zum Beispiel:
Hier
census
ist ein Attribut derCat
Klasse auf Klassenebene.Beachten Sie, dass Sie nicht bekommen
[fluffy, sparky]
. Das sind nur Variablennamen. Wenn Sie möchten, dass Katzen selbst Namen haben, müssen Sie ein separates Attribut für den Namen erstellen und dann die__str__
Methode überschreiben , um diesen Namen zurückzugeben. Der Zweck dieser Methode (dh klassengebundene Funktion, genau wieadd
oder__init__
) besteht darin, zu beschreiben, wie das Objekt in eine Zeichenfolge konvertiert wird, beispielsweise beim Ausdrucken.quelle
Um meine 5 Cent zur gründlichen Erklärung von Amadan beizutragen .
Wobei Klassen eine abstrakte Beschreibung "eines Typs" sind. Objekte sind ihre Erkenntnisse: das lebendige Atmen. In der objektorientierten Welt gibt es Hauptideen, die man fast als die Essenz von allem bezeichnen kann. Sie sind:
Objekte haben eine oder mehrere Eigenschaften (= Attribute) und Verhaltensweisen (= Methoden). Das Verhalten hängt hauptsächlich von den Eigenschaften ab. Klassen definieren, was das Verhalten allgemein erreichen soll, aber solange die Klasse nicht als Objekt realisiert (instanziiert) wird, bleibt sie ein abstraktes Konzept einer Möglichkeit. Lassen Sie mich mit Hilfe von "Vererbung" und "Polymorphismus" veranschaulichen.
Einige Eigenschaften definieren den Menschen. Aber jede Nationalität ist etwas anders. "National-Typen" sind also Menschen mit Extras. "Amerikaner" sind eine Art von "Menschen" und erben einige abstrakte Merkmale und Verhaltensweisen vom menschlichen Typ (Basisklasse): das ist Vererbung. So können alle Menschen lachen und trinken, also auch alle Kinderklassen! Vererbung (2).
Aber weil sie alle von der gleichen Art sind (Typ / Basisklasse: Menschen), können Sie sie manchmal austauschen: siehe die for-Schleife am Ende. Aber sie werden ein individuelles Merkmal aufdecken, und das ist Polymorphismus (3).
Jeder Mensch hat also ein Lieblingsgetränk, aber jede Nationalität tendiert zu einer besonderen Art von Getränk. Wenn Sie eine Nationalität vom Typ Mensch unterordnen, können Sie das ererbte Verhalten überschreiben, wie ich oben mit der
drink()
Methode gezeigt habe. Aber das ist immer noch auf Klassenebene und aus diesem Grund ist es immer noch eine Verallgemeinerung.instanziiert die Klasse Deutsch und ich habe am Anfang ein Standardmerkmal "geändert". (Aber wenn Sie hans.drink ('Milk') nennen, würde er immer noch "Ich brauche mehr Bier" drucken - ein offensichtlicher Fehler ... oder vielleicht würde ich das eine Funktion nennen, wenn ich ein Mitarbeiter eines größeren Unternehmens wäre. ;-)! )
Die Eigenschaften eines Typs, z. B. Deutsche (Hans), werden normalerweise
__init__
zum Zeitpunkt der Instanziierung durch den Konstruktor (in Python :) definiert. Dies ist der Punkt, an dem Sie eine Klasse definieren, um ein Objekt zu werden. Man könnte sagen, einem abstrakten Konzept (einer Klasse) Leben einzuhauchen, indem man es mit individuellen Merkmalen füllt und ein Objekt wird.Da jedoch jedes Objekt eine Instanz einer Klasse ist, teilen sie alle grundlegenden Merkmalstypen und Verhaltensweisen. Dies ist ein wesentlicher Vorteil des objektorientierten Konzepts.
Um die Eigenschaften jedes Objekts zu schützen, kapseln Sie sie ein. Dies bedeutet, dass Sie versuchen, Verhalten und Eigenschaften zu koppeln und es schwierig zu machen, sie von außerhalb des Objekts zu manipulieren. Das ist Verkapselung (1)
quelle
Es dient lediglich dazu, die Variablen der Instanz zu initialisieren.
Erstellen Sie beispielsweise eine
crawler
Instanz mit einem bestimmten Datenbanknamen (aus dem obigen Beispiel).quelle
left=None
left wird initialisiert,None
wenn bei der Erstellung derleft
Parameter nicht angegeben wird.left = foo
würde funktionieren - einmal. Der Sinn des Unterrichts ist es, für jeden etwas Vernünftiges zu tuncrawler
. Klassen sind weder Funktionen noch etwas, das mit Funktionen verglichen werden kann (naja, erst wenn Sie viel fortgeschrittener sind und in die funktionale Programmierung einsteigen, aber das wird Sie jetzt nur verwirren). Lesen Sie meine Antwort, was Klassen eigentlich sind - Sie bekommen es immer noch nicht.Es scheint, als müssten Sie
__init__
Python verwenden, wenn Sie veränderbare Attribute Ihrer Instanzen korrekt initialisieren möchten.Siehe folgendes Beispiel:
Dies ist in Java ganz anders, wo jedes Attribut automatisch mit einem neuen Wert initialisiert wird:
erzeugt eine Ausgabe, die wir intuitiv erwarten:
Wenn Sie jedoch
attr
als deklarierenstatic
, verhält es sich wie Python:quelle
Folgen Sie Ihrem Auto- Beispiel: Wenn Sie ein Auto bekommen, bekommen Sie einfach kein zufälliges Auto, ich meine, Sie wählen die Farbe, die Marke, die Anzahl der Sitze usw. Und einige Dinge werden auch ohne Ihre Wahl "initialisiert" dafür, wie Anzahl der Räder oder Kennzeichen.
In der
__init__
Methode definieren Sie also die Attribute der Instanz, die Sie erstellen. Wenn wir also ein blaues Renault-Auto für 2 Personen wollen, würden wir Folgendes initialisieren oder instanziierenCar
:Auf diese Weise erstellen wir eine Instanz von
Car
Klasse. Das__init__
ist dasjenige, das unsere spezifischen Attribute (wiecolor
oderbrand
) behandelt und die anderen Attribute wie erzeugtregistration_number
.__init__
Methodequelle
Klassen sind Objekte mit Attributen (Zustand, Charakteristik) und Methoden (Funktionen, Kapazitäten), die für dieses Objekt spezifisch sind (wie die weiße Farbe bzw. die Flugkraft für eine Ente).
Wenn Sie eine Instanz einer Klasse erstellen, können Sie ihr eine anfängliche Persönlichkeit geben (Zustand oder Charakter wie der Name und die Farbe ihres Kleides für ein Neugeborenes). Du machst das mit
__init__
.Grundsätzlich
__init__
werden die Instanzmerkmale beim Aufruf automatisch festgelegtinstance = MyClass(some_individual_traits)
.quelle
Die
__init__
Funktion richtet alle Mitgliedsvariablen in der Klasse ein. Sobald Ihr Bicluster erstellt ist, können Sie auf das Mitglied zugreifen und einen Wert zurückerhalten:In den Python-Dokumenten finden Sie einige Informationen. Sie sollten ein Buch über OO-Konzepte lesen, um weiter zu lernen.
quelle
Im obigen Beispiel verwenden wir Arten als global, da sie immer gleich sind (Art von Konstante kann man sagen). Wenn Sie die
__init__
Methode aufrufen , wird die gesamte darin enthaltene Variable__init__
initiiert (z. B. Rasse, Name).Wenn Sie das obige Beispiel ausdrucken, indem Sie unten wie folgt aufrufen
Das heißt, es wird nur während der Objekterstellung initialisiert. Alles, was Sie als konstant deklarieren möchten, wird global und alles, was geändert wird, wird verwendet
__init__
quelle