Python, creando oggetti


132

Sto cercando di imparare Python e ora sto cercando di imparare le lezioni e come manipolarle con le istanze.

Non riesco a capire questo problema pratico:

Crea e restituisci un oggetto studente il cui nome, età e maggiore siano gli stessi di quelli indicati come input

def make_student(name, age, major)

Semplicemente non capisco cosa significhi per oggetto, significano che dovrei creare un array all'interno della funzione che contiene questi valori? o creare una classe e lasciare che questa funzione sia al suo interno e assegnare istanze? (prima di questa domanda mi è stato chiesto di organizzare una classe di studenti con nome, età e maggiore all'interno)

class Student:
    name = "Unknown name"
    age = 0
    major = "Unknown major"

Leggi i documenti del modello di dati, in particolare il __init__metodo è pertinente qui: docs.python.org/2/reference/datamodel.html#object.__init__
wim

1
Nessuno (senza virgolette) è il valore predefinito non assegnato comune in python
monkut il

Risposte:


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

Nota che anche se uno dei principi della filosofia di Python è "dovrebbe esserci uno - e preferibilmente solo uno - un modo ovvio per farlo" , ci sono ancora molti modi per farlo. Puoi anche usare i due seguenti frammenti di codice per sfruttare le capacità dinamiche di Python:

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

Preferisco il primo, ma ci sono casi in cui il secondo può essere utile - uno è quando si lavora con database di documenti come MongoDB.


17
perché le stai inizializzando come variabili di classe prima del tuo init? (curioso; non ho visto questo schema molto spesso)
GoingTharn,

7
Ai fini della leggibilità. Mettendo le variabili di classe vicino all'inizio prima dell'init, posso vedere rapidamente quali variabili rientrano nell'ambito della classe poiché potrebbero non essere tutte impostate dal costruttore.
Wulfram,

1
Qui il nome dell'oggetto che è l'istanza della classe Student rimarrà studente giusto? Cosa succede se voglio più oggetti ad ogni chiamata con il nome student01, student02, .. e così via?
Yathi,

9
Creare variabili di classe per vedere quali sono le tue variabili di istanza è una pratica terribile. A tutti i lettori alle prime armi: guarda invece la risposta di @ pyrospade.
anon01,

2
Il tuo esempio è fuorviante. Si prega di utilizzare i nomi delle variabili di classe che sono in realtà una proprietà di tutti gli studenti, piuttosto che abusare di una proprietà di ogni studente. Ad esempio: utilizzare class Unicorne has_hooves = Trueinvece di name = "".
Tim Kuipers,

49

Crea una classe e dagli un __init__metodo:

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

Ora puoi inizializzare un'istanza della Studentclasse:

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

Anche se non sono sicuro del motivo per cui hai bisogno di una make_studentfunzione studente se fa la stessa cosa Student.__init__.


Il nostro insegnante ci ha fornito un programma test.py che verifica se i problemi sono stati eseguiti correttamente. La domanda vuole che io usi specificamente la funzione make_student. L'obiettivo finale è: s1 = make_student (nome, età, maggiore) e ora ho tutto assegnato a s1. Ma ancora non sono sicuro di cosa vogliano essere s1? Posso farlo con un array {'name': name..etc} ma questo non mi ha dato una risposta corretta, quindi presumo di dover implementare ciò che ho imparato da classi e istanze
Mohsen M. Alrasheed,

1
Il cosiddetto modello "metodo di fabbrica", quello in cui si utilizza un metodo o una funzione per creare oggetti di qualche tipo invece di crearli direttamente nel codice, è un modello utile, che consente ad esempio di sfruttare belle cose sull'eredità . Guardalo in alto;)
bracco23

28

Gli oggetti sono istanze di classi. Le classi sono solo i progetti per gli oggetti. Quindi, data la tua definizione di classe -

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

È possibile creare una make_studentfunzione assegnando esplicitamente gli attributi a una nuova istanza di Student-

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

Ma probabilmente ha più senso farlo in un costruttore ( __init__) -

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

Il costruttore viene chiamato quando si utilizza Student(). Prenderà gli argomenti definiti nel __init__metodo. La firma del costruttore ora sarebbe essenzialmente Student(name, age, major).

Se lo usi, allora una make_studentfunzione è banale (e superflua) -

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

Per divertimento, ecco un esempio di come creare una make_studentfunzione senza definire una classe. Per favore, non provarlo a casa.

def make_student(name, age, major):
    return type('Student', (object,),
                {'name': name, 'age': age, 'major': major})()

In realtà, preferisco non fare il nome della classe (oggetto): per motivi di verbosità. Anche la documentazione di Python tende a non farlo. Mi piace l'esempio "pericoloso" di alimentazione in un dict però. docs.python.org/2/tutorial/classes.html
Wulfram,

1
Ritiro il mio commento precedente. Vedi stackoverflow.com/questions/4015417/… . Quindi c'è in realtà un motivo per precisare il nome della classe (oggetto):
Wulfram,

1
Non c'è nessun costruttore in Python :)
BigSack

In che modo il __init__()metodo è diverso da un costruttore?
pyrospade,

1
__init__non è un costruttore, "perché l'oggetto è già stato costruito quando __init__viene chiamato il tempo e hai già un riferimento valido alla nuova istanza della classe". ( diveintopython.net/object_oriented_framework/… )
Brian Z

3

quando si crea un oggetto utilizzando la classe predefinita, all'inizio si desidera creare una variabile per la memorizzazione di tale oggetto. Quindi è possibile creare oggetti e memorizzare variabili che sono state create.

class Student:
     def __init__(self):

# creating an object....

   student1=Student()

In realtà questo metodo init è il costruttore di class.you può inizializzare quel metodo usando alcuni attributi .. In quel punto, quando crei un oggetto, dovrai passare alcuni valori per attributi particolari ..

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

 # creating an object.......

     student2=Student("smith",25)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.