2015-04-11 12 views
6

Ho una struttura simile a questa:chiamata Python oggetto in funzione senza passare la chiamata oggetto

def foobar(): 
    print('FOOBAR!') 

class SampleClass: 
    foo = foobar 
    def printfunc(self): 
     self.foo() 

Questo non funziona perché la funzione foobar originale non può gestire self essere passato ad esso - - Non faceva parte di alcuna classe o oggetto per cominciare. Python non mi consente di aggiungere il decoratore @staticmethod.

Non ho il controllo sulla definizione di foobar e potrei dover sostituire il valore di foo in sottoclassi.

Come posso chiamare foo, senza passare l'oggetto chiamandolo?

+0

Sono un po 'confuso. Perché non definire la funzione 'foobar' all'interno di' SampleClass'? – Huey

+1

Perché non solo "def foo (auto): foobar()'? – user2357112

+0

@Huey Perché in questo caso specifico, è * non * qualcosa che posso definire. È un metodo esterno e verrà sovrascritto con un altro metodo esterno in una sottoclasse. –

risposta

6

Decorators are plain functions, si dovrebbe essere in grado di chiamare staticmethod(foobar) esplicitamente nella definizione della classe

class SampleClass: 
    foo = staticmethod(foobar) 
    def printfunc(self): 
     self.foo() # Prints 'FOOBAR!' 
2

L'approccio dal commento di user2357112 sembra funzionare, anche:

def foobar(): 
     print('FOOBAR!') 

def foobaz(): 
     print('FooBAZ!') 

class SampleClass: 
     def foo(self): 
       foobar() 

     def printfunc(self): 
       self.foo() 

class DerivedClass(SampleClass): 
     def foo(self): 
       foobaz() 

sample = SampleClass() 
sample.printfunc() # FOOBAR! 

derived = DerivedClass() 
derived.printfunc() # FooBAZ! 

Se i valori di ritorno deve fare attraverso , sono necessarie le dichiarazioni return a tutti i livelli, tuttavia:

def foobar(): 
     print('FOOBAR!') 
     return 'foo' 

def foobaz(): 
     print('FooBAZ!') 
     return 'baz' 

class SampleClass: 
     def foo(self): 
       return foobar() 

     def printfunc(self): 
       return self.foo() 

class DerivedClass(SampleClass): 
     def foo(self): 
       return foobaz() 

sample = SampleClass() 
s = sample.printfunc() # FOOBAR! 
print(s) # foo 

derived = DerivedClass() 
d = derived.printfunc() # FooBAZ! 
print(d) # baz 
+0

Non è semplicemente sufficiente per eseguire la funzione con una seconda funzione, penso. Dovevo molto sfoltire l'esempio che ho dato ai suoi componenti più semplici, ma ci sono alcune dichiarazioni di "yield" che fluttuano anche lì - non sono sicuro di come questo possa influenzarle. –

+2

Bene, sebbene sia apprezzato (e atteso) che si riducano gli esempi alle parti pertinenti, assicurarsi che tutto ciò che * è * rilevante (per te/per il tuo problema o domanda) sia ancora incluso. [Il rasoio di Einstein] (https://en.wikiquote.org/wiki/Albert_Einstein) è importante quanto quello di Occam. –

+1

@ Z̷͙̗̻͖̣̹͉̫̬̪̖̤͆ͤ̓ͫͭ̐͜͞αлγo: Dovrebbe funzionare bene. 'foobar' è una funzione generatore, e' foo' non lo sarà, ma 'foo' dovrebbe restituire l'iteratore del generatore restituito da' foobar' come se 'foo' fosse una funzione generatore stessa. – user2357112