2015-04-11 7 views
6

Mam strukturę coś takiego:połączeń Python obiektu jako funkcji bez przechodzenia wywołującego obiektu

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

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

To nie działa, ponieważ pierwotna funkcja foobar nie może obsłużyć self były przekazywane do niej - - na początku nie była częścią żadnej klasy ani obiektu. Python nie pozwoli mi dodać dekoratora @staticmethod.

Nie mam żadnej kontroli nad definicją foobar i może być konieczne przesłonięcie wartości foo w podklasach.

Jak mogę wywołać funkcję foo, nie przekazując obiektu, który ją wywołuje?

+0

Jestem trochę zdezorientowany. Dlaczego nie zdefiniować funkcji 'foobar' w swoim' SampleClass'? – Huey

+1

Dlaczego nie po prostu 'def foo (self): foobar()'? – user2357112

+0

@Huey Ponieważ w tym konkretnym przypadku jest to * nie * coś, co mogę zdefiniować. Jest to metoda zewnętrzna i zostanie nadpisana inną metodą zewnętrzną w podklasie. –

Odpowiedz

6

Decorators are plain functions, powinieneś być w stanie wywołać staticmethod(foobar) wprost w definicji klasy

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

Podejście z komentarzem user2357112 wydaje się działać także:

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! 

Jeśli zwracane wartości dokonuje się poprzez , potrzebujesz instrukcji na wszystkich poziomach:

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

To nie wystarczy, aby uruchomić funkcję z drugą funkcją, jak sądzę. Musiałem znacznie przyciąć przykład, który dałem swoim najprostszym komponentom, ale są tam też pewne instrukcje "yield", nie wiem, jak to by miało na nich wpływ. –

+2

Cóż, chociaż jest doceniane (i oczekiwano), że gotujesz przykłady do odpowiednich części, upewnij się, że wszystko, co * jest * istotne (dla ciebie/twojego problemu lub pytania) jest nadal uwzględnione. [Maszynka do golenia Einsteina] (https://en.wikiquote.org/wiki/Albert_Einstein) jest równie ważna jak Ockhama. –

+1

@ Z̷͙̗̻͖̣̹͉̫̬̪̖̤͆ͤ̓ͫͭ̐͜͞αлγo: Powinno działać dobrze. 'foobar' jest funkcją generatora, a' foo' nie będzie, ale 'foo' powinien zwrócić iterator generatora zwrócony przez' foobar' tak, jakby 'foo' był samą funkcją generatora. – user2357112

Powiązane problemy