Chiamare una funzione di classe all'interno di __init__


132

Sto scrivendo del codice che accetta un nome file, apre il file ed analizza alcuni dati. Mi piacerebbe farlo in una classe. Il seguente codice funziona:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None

        def parse_file():
            #do some parsing
            self.stat1 = result_from_parse1
            self.stat2 = result_from_parse2
            self.stat3 = result_from_parse3
            self.stat4 = result_from_parse4
            self.stat5 = result_from_parse5

        parse_file()

Ma mi coinvolge mettendo tutti i macchinari di analisi nell'ambito della __init__funzione per la mia classe. Ora sembra a posto per questo codice semplificato, ma la funzione parse_fileha anche alcuni livelli di rientro. Preferirei definire la funzione parse_file()come una funzione di classe come di seguito:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        parse_file()

    def parse_file():
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

Naturalmente questo codice non funziona perché la funzione parse_file()non rientra nell'ambito della __init__funzione. C'è un modo per chiamare una funzione di classe dall'interno __init__di quella classe? O sto pensando a questo nel modo sbagliato?


C'è qualche motivo per cui l'esempio di codice necessita di cinque versioni di "stat"? Sarebbe più facile da leggere se ce ne fosse solo uno.
— 465b

Risposte:


183

Chiamare la funzione in questo modo:

self.parse_file()

Devi anche definire la tua funzione parse_file () in questo modo:

def parse_file(self):

Il parse_filemetodo deve essere associato a un oggetto dopo averlo chiamato (perché non è un metodo statico). Questo viene fatto chiamando la funzione su un'istanza dell'oggetto, nel tuo caso l'istanza è self.


Sì! Questo era esattamente quello che stavo cercando. Grazie!
— PythonJin,

33

Se non sbaglio, entrambe le funzioni fanno parte della tua classe, dovresti usarla in questo modo:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        self.parse_file()

    def parse_file(self):
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

sostituisci la tua linea:

parse_file() 

con:

self.parse_file()

Potresti spiegare perché deve essere usato self.parse_file()e non parse_file()?
— Ivanleoncz,

@paritoshsingh def parse_file(self):non dovrebbe essere nidificato sotto la __init__funzione in modo da non avere un oggetto parzialmente inizializzato?
— donrondadon,

@ivanleoncz Poiché parse_file è il metodo di istanza, è necessario utilizzare l'oggetto di riferimento per chiamare lo stesso.
— Paritosh Singh,

@rong Se questo codice è venerabile e non si desidera consentire l'impostazione del file di analisi dall'esterno, sì, dovrebbe essere nidificato.
— Paritosh Singh,

12

Che ne dite di:

class MyClass(object):
    def __init__(self, filename):
        self.filename = filename 
        self.stats = parse_file(filename)

def parse_file(filename):
    #do some parsing
    return results_from_parse

A proposito, se si dispone di variabili chiamate stat1, stat2e così via, la situazione è accattonaggio per una tupla: stats = (...).

Quindi lascia che parse_filerestituisca una tupla e riponila self.stats.

Quindi, per esempio, è possibile accedere a ciò che veniva chiamato stat3con self.stats[2].


Sono d'accordo, ho appena inserito self.stat1 attraverso self.stat5 per mostrare che c'erano alcune variabili di classe che stavo assegnando. Nel codice attuale ho una soluzione più elegante.
— PythonJin,

Come dovrebbe essere modificato se voglio che la parse_filefunzione sia un metodo MyClassdell'oggetto. Dove sarebbe selfnecessario?
— n1k31t4,

0

In parse_file, prendi l' selfargomento (proprio come in __init__). Se c'è qualche altro contesto di cui hai bisogno, passa semplicemente come argomenti aggiuntivi come al solito.


0

Devi dichiarare parse_file in questo modo; def parse_file(self). Il parametro "self" è un parametro nascosto nella maggior parte delle lingue, ma non in Python. È necessario aggiungerlo alla definizione di tutti quei metodi che appartengono a una classe. Quindi è possibile chiamare la funzione da qualsiasi metodo all'interno della classe utilizzandoself.parse_file

il tuo programma finale sarà simile al seguente:

class MyClass():
  def __init__(self, filename):
      self.filename = filename 

      self.stat1 = None
      self.stat2 = None
      self.stat3 = None
      self.stat4 = None
      self.stat5 = None
      self.parse_file()

  def parse_file(self):
      #do some parsing
      self.stat1 = result_from_parse1
      self.stat2 = result_from_parse2
      self.stat3 = result_from_parse3
      self.stat4 = result_from_parse4
      self.stat5 = result_from_parse5

-13

Penso che il tuo problema sia in realtà con la funzione init non rientrata correttamente. Dovrebbe essere così

class MyClass():
     def __init__(self, filename):
          pass

     def parse_file():
          pass

Né è il tuo codice. A meno che tu non abbia messo il @staticmethoddecoratore sopra parse_file
— rantanplan il

almeno aggiungi ciò che manca selfnel tuo parse_filemetodo.
— rantanplan,

Spiacenti, ci sarebbe dovuto essere un ulteriore livello di rientro nella riga "class MyClass ():". L'ho risolto sopra, ma la domanda rimane la stessa.
— PythonJin,
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.