2013-01-18 19 views
9

Ho lavorato per anni nella programmazione C di basso livello e non ho abbastanza esposizione agli approcci orientati agli oggetti. In C, se stavo sviluppando un'architettura a strati, ogni livello ha interfacce definite da puntatori di funzione. Il vantaggio è che l'intero livello può essere sostituito semplicemente impostando quei puntatori di funzione all'inizializzazione su un altro livello.sostituto dei puntatori di funzione in python

Voglio la stessa cosa ma questa volta in Python. Qual è il modo più bello per riuscirci. Per dare un po 'di background al mio problema, ho un generatore di dati che può emettere record su supporti diversi. Il supporto è specificato al momento della configurazione. Non voglio usare if o cambiare le istruzioni qui. Il modo migliore era usare i puntatori di funzione in C, ma quali sono le opzioni disponibili qui in Python. Sono anche apprezzati tutti gli approcci orientati agli oggetti.

Grazie

+0

un'occhiata a polimorfismo http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming –

risposta

14

Python supporta le funzioni come un tipo di dati di prima classe. Così si può fare qualcosa di simile:

def foo(x): 
    print("foo: " + x) 

def bar(x): 
    print("bar: " + x) 

f = foo 
f("one") 
f = bar 
f("ten") 

stampe

foo: one 
bar: ten 

Questo è molto simile alla vostra esperienza con puntatori a funzione in C. Anche se Python supporta certamente stili di programmazione orientata agli oggetti più elaborati, si è sotto nessun obbligo di usarli.

Un esempio utilizzando le classi, in cui è possibile raggruppare insieme le funzioni relative:

class Dog: 
    def noise(self, x): 
     print("bark! " + x) 
    def sleep(self): 
     print("sleeping on floor") 

class Cat: 
    def noise(self, x): 
     print("meow! " + x) 
    def sleep(self): 
     print("sleeping on keyboard") 

a = Dog() 
a.noise("hungry") 
a.sleep() 

a = Cat() 
a.noise("hungry") 
a.sleep() 

Questa versione stampa:

bark! hungry 
sleeping on floor 
meow! hungry 
sleeping on keyboard 
+1

MALEDIZIONI, sventato ancora una volta! – argentage

+0

+1. Potrebbe valere la pena di aggiungere un esempio che mostra con quanta facilità si possa portare l'idioma C di "table of function pointers" (che è dove penso che l'OP sta andando) a un semplice 'dict' di funzioni. – abarnert

+0

Grazie, sembra bello ... ma puoi elaborare altre opzioni o stili di programmazione per raggiungere questo obiettivo. –

2

a funzioni Python sono i tipi di dati di prima classe.

def z(a): 
    print(a) 
def x(a): 
    print "hi" 

functions = [z,x] 
y = functions[0] 
y("ok") # prints "ok" 
y = functions[1] 
y("ok") # prints "hi" 
+1

Si noti che "valore di prima classe" significa molto di più dei puntatori di funzione: ad esempio, nuove funzioni possono essere create in fase di runtime. – delnan

3

Forse qualcosa alog queste righe:

class MediumA: 
    def one_method(self): 
     return 

    def another_method(self): 
     return 

class MediumB: 
    def one_method(self): 
     return 

    def another_method(self): 
     return 


class DataGenerator: 
    # here you can read this from some configuration 
    medium = MediumA() # this will be shared between all instances of DataGenerator 

    def generate(self): 
     # all mediums responds to this methods 
     medium.one_method() 
     medium.another_method() 

generator = DataGenerator() 
# you can even change the medium here 
generator.medium = MediumB() 

Speranza che aiuta

4

Si può semplicemente inserire le funzioni in un dict

{"type1": function1, 
"type2": function2, 
"type3": function3, 
}.get(config_option, defaultfunction)(parameters, go, here) 

default_function viene chiamato se nessuno dei le chiavi corrispondono allo

Se lo si desidera è possibile separare la selezione di un chiamante

selected_function = {"type1": function1, 
        "type2": function2, 
        "type3": function3, 
        }.get(config_option, defaultfunction) 

some_instance = SomeClass(selected_function)