2013-02-24 8 views
5

Python permette di assegnare una funzione predefinita a una classe come attributo, come ad esempioAssegnare le funzioni come attributi di un oggetto, quindi chiamare senza l'implicito "auto" argomentazione?

def fish_slap(fish): 
    # do something 

class dance(object): 
    dance_move=fish_slap 

Tuttavia, se proviamo non dire

d=dance() 
d.dance_move("Halibut") 

otteniamo il il seguente errore

TypeError: fish_slap() takes exactly 1 arguement (2 given) 

Python sembra visualizzare questo come un metodo di oggetto e fornisce l'argomento implicito di "sé". Abbastanza corretto, sembra che abbia appena imparato che assegnare una funzione come attributo in questo modo equivale a definire la funzione direttamente all'interno della classe. Vedo che questa è una caratteristica utile.

Tuttavia, in questo caso questo non è quello che voglio. Nella mia applicazione ho modelli statistici codificati come classi diverse che hanno anche i loro metodi "train" per addestrare i parametri del modello rispetto ai dati forniti. Per fare ciò, una funzione obiettivo che desideri minimizzare (o massimizzare) il valore dei bisogni da fornire. Un esempio semplice funzione obiettivo è dire

def RMSE(predicted,observed): 
    "Root mean squared error" 
    return sp.sqrt(sp.mean((predicted-observed)**2)) 

dove SciPy è stato importato come sp. Queste funzioni oggettive sono definite in un singolo file .py e sono usate nel mio codice e naturalmente esistono come funzioni autonome, piuttosto che come metodi di classe con l'argomento implicito di "sé".

voglio essere in grado di impostare la funzione obiettivo desiderato come attributo modo che le parti successive un oggetto del modello non utilizza tale funzione, ad esempio

some_model=SomeModel(initial_parameter_values_guess) 
some_model.objective_function = RMSE 
some_model.train(training_data) 
predictions_RMSE = some_model.predict() 
some_mode.objective_function = MAE 
predictions_MAE = some_model.predict() 

In questo esempio è sembra ho potuto solo passare la funzione oggettiva come argomento da addestrare, tuttavia nella mia applicazione c'è molto di più che si vorrebbe fare e sembra avere più senso essere in grado di impostare/ottenere la funzione obiettivo piuttosto che ripetutamente fornendola come argomento.

Esistono numerosi metodi per ottenere questo comportamento di base, ma qual è l'approccio più pionico?

Si noti che il mio codice corrente è conforme a python2 e python3. Se ci sono soluzioni specifiche per le versioni, segnalalo. Sto lavorando con python2 per poter usare matplotlib ma sto cercando di assicurarmi che il codice sia compatibile con python3 a parte quel modulo.

+0

Perché non cambi semplicemente 'def fish_slap (fish):' a 'def fish_slap (self, fish):'? – Blender

+0

@Blender, vedere il paragrafo dopo la definizione di RMSE. Queste funzioni sono già definite e utilizzate in molti altri posti come funzioni indipendenti senza l'argomento 'self'. – Bogdanovist

risposta

8

È possibile utilizzare un staticmethod

class dance(object): 
    dance_move=staticmethod(fish_slap) 

Si noti che non è necessario utilizzare staticmethod se si sta assegnando a un attributo di un esempio:

>>> def move(): 
...  print "disco party!" 
... 
>>> class dance(object): 
...  dance_move = staticmethod(move) 
... 
>>> d = dance() 
>>> d.dance_move() 
disco party! 
>>> d.break_it_down = move 
>>> d.break_it_down() 
disco party! 
+0

Perfetto. Chiaramente sono ancora molto un python n00b. – Bogdanovist

Problemi correlati