Python, Objekte erstellen

132

Ich versuche Python zu lernen und jetzt versuche ich, den Dreh raus zu bekommen und wie man sie mit Instanzen manipuliert.

Ich kann dieses Übungsproblem nicht verstehen:

Erstellen Sie ein Schülerobjekt und geben Sie es zurück, dessen Name, Alter und Hauptfach mit den als Eingabe angegebenen übereinstimmen

def make_student(name, age, major)

Ich verstehe einfach nicht, was es mit Objekt bedeutet. Bedeuten sie, dass ich ein Array innerhalb der Funktion erstellen sollte, die diese Werte enthält? oder eine Klasse erstellen und diese Funktion darin enthalten lassen und Instanzen zuweisen? (Vor dieser Frage wurde ich gebeten, eine Schülerklasse mit Namen, Alter und Hauptfach einzurichten.)

class Student:
    name = "Unknown name"
    age = 0
    major = "Unknown major"
Mohsen M. Alrasheed
quelle
Lesen Sie die Datenmodelldokumente, insbesondere ist die __init__Methode hier relevant: docs.python.org/2/reference/datamodel.html#object.__init__
wim
1
Keine (keine Anführungszeichen) ist der übliche nicht zugewiesene Standardwert in Python
Monkut

Antworten:

173
class Student(object):
    name = ""
    age = 0
    major = ""

    # The class "constructor" - It's actually an initializer 
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

def make_student(name, age, major):
    student = Student(name, age, major)
    return student

Beachten Sie, dass es, obwohl eines der Prinzipien in Pythons Philosophie lautet: "Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun" , immer noch mehrere Wege gibt, dies zu tun. Sie können auch die beiden folgenden Codeausschnitte verwenden, um die dynamischen Funktionen von Python zu nutzen:

class Student(object):
    name = ""
    age = 0
    major = ""

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    # Note: I didn't need to create a variable in the class definition before doing this.
    student.gpa = float(4.0)
    return student

Ich bevorzuge Ersteres, aber es gibt Fälle, in denen Letzteres nützlich sein kann - einer bei der Arbeit mit Dokumentendatenbanken wie MongoDB.

Wulfram
quelle
17
Warum initialisieren Sie sie als Klassenvariablen vor Ihrer Init? (neugierig; habe dieses Muster nicht sehr oft gesehen)
GoingTharn
7
Aus Gründen der Lesbarkeit. Indem ich die Klassenvariablen vor dem Init in den oberen Bereich setze, kann ich schnell erkennen, welche Variablen sich im Klassenbereich befinden, da sie möglicherweise nicht alle vom Konstruktor festgelegt werden.
Wulfram
1
Hier bleibt der Name des Objekts, das die Instanz der Klasse Student ist, Student, oder? Was ist, wenn ich bei jedem Aufruf mehrere Objekte mit den Namen student01, student02 usw. haben möchte?
Yathi
9
Das Erstellen von Klassenvariablen, um zu sehen, was Ihre Instanzvariablen sind, ist eine schreckliche Praxis. Für alle unerfahrenen Leser: Schauen Sie sich stattdessen die Antwort von @ pyrospade an.
anon01
2
Ihr Beispiel ist irreführend. Bitte verwenden Sie Klassenvariablennamen, die in Wirklichkeit eine Eigenschaft aller Schüler sind, anstatt eine Eigenschaft jedes Schülers zu missbrauchen. Zum Beispiel: benutze class Unicornund has_hooves = Trueanstelle von name = "".
Tim Kuipers
49

Erstellen Sie eine Klasse und geben Sie ihr eine __init__Methode:

class Student:
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

    def is_old(self):
        return self.age > 100

Jetzt können Sie eine Instanz der StudentKlasse initialisieren :

>>> s = Student('John', 88, None)
>>> s.name
    'John'
>>> s.age
    88

Obwohl ich nicht sicher bin, warum Sie eine make_studentStudentenfunktion benötigen, wenn sie dasselbe tut wie Student.__init__.

Mixer
quelle
Unser Lehrer gab uns ein test.py-Programm, das testet, ob wir die Probleme richtig gemacht haben. Die Frage möchte, dass ich speziell die Funktion make_student verwende. Das Endziel ist: s1 = make_student (Name, Alter, Hauptfach) und jetzt habe ich alles s1 zugewiesen. Aber ich bin mir wieder nicht sicher, was s1 sein soll? Ich kann dies mit einem Array {'name': name..etc} tun, aber das gab mir keine richtige Antwort, daher gehe ich davon aus, dass ich das implementieren muss, was ich aus Klassen und Instanzen gelernt habe
Mohsen M. Alrasheed
1
Das sogenannte "Factory-Methoden" -Muster, bei dem Sie eine Methode oder eine Funktion verwenden, um Objekte zu erstellen, anstatt sie direkt im Code zu erstellen, ist ein nützliches Muster, mit dem Sie beispielsweise nützliche Aspekte der Vererbung ausnutzen können . Schau nach;)
bracco23
28

Objekte sind Instanzen von Klassen. Klassen sind nur die Blaupausen für Objekte. Also angesichts Ihrer Klassendefinition -

# Note the added (object) - this is the preferred way of creating new classes
class Student(object):
    name = "Unknown name"
    age = 0
    major = "Unknown major"

Sie können eine make_studentFunktion erstellen, indem Sie die Attribute explizit einer neuen Instanz von Student- zuweisen

def make_student(name, age, major):
    student = Student()
    student.name = name
    student.age = age
    student.major = major
    return student

Aber es ist wahrscheinlich sinnvoller, dies in einem Konstruktor ( __init__) zu tun -

class Student(object):
    def __init__(self, name="Unknown name", age=0, major="Unknown major"):
        self.name = name
        self.age = age
        self.major = major

Der Konstruktor wird bei Verwendung aufgerufen Student(). Es werden die in der __init__Methode definierten Argumente verwendet. Die Konstruktorsignatur wäre nun im Wesentlichen Student(name, age, major).

Wenn Sie das verwenden, ist eine make_studentFunktion trivial (und überflüssig) -

def make_student(name, age, major):
    return Student(name, age, major)

Zum Spaß finden Sie hier ein Beispiel, wie Sie eine make_studentFunktion erstellen , ohne eine Klasse zu definieren. Bitte versuchen Sie dies nicht zu Hause.

def make_student(name, age, major):
    return type('Student', (object,),
                {'name': name, 'age': age, 'major': major})()
Pyrospade
quelle
Eigentlich ziehe ich es vor, keinen Klassennamen (Objekt) zu machen: aus Gründen der Ausführlichkeit. Die Python-Dokumentation tut dies in der Regel nicht so gut. Ich mag das "gefährliche" Beispiel, ein Diktat einzugeben. docs.python.org/2/tutorial/classes.html
Wulfram
1
Ich ziehe meinen vorherigen Kommentar zurück. Siehe stackoverflow.com/questions/4015417/… . Es gibt also tatsächlich einen Grund, den Klassennamen (Objekt) zu buchstabieren:
Wulfram
1
Es gibt keinen Konstruktor in Python :)
BigSack
Wie unterscheidet sich die __init__()Methode von einem Konstruktor?
Pyrospade
1
__init__ist kein Konstruktor, "weil das Objekt zum Zeitpunkt des Aufrufs bereits erstellt wurde __init__und Sie bereits einen gültigen Verweis auf die neue Instanz der Klasse haben." ( diveintopython.net/object_oriented_framework/… )
Brian Z
3

Wenn Sie ein Objekt mit einer vordefinierten Klasse erstellen, möchten Sie zunächst eine Variable zum Speichern dieses Objekts erstellen. Anschließend können Sie ein Objekt erstellen und eine von Ihnen erstellte Variable speichern.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

Tatsächlich ist diese init- Methode der Konstruktor der Klasse. Sie können diese Methode mithilfe einiger Attribute initialisieren. Wenn Sie ein Objekt erstellen, müssen Sie an diesem Punkt einige Werte für bestimmte Attribute übergeben.

class Student:
      def __init__(self,name,age):
            self.name=value
            self.age=value

 # creating an object.......

     student2=Student("smith",25)
GT_hash
quelle