2012-08-16 15 views
11

Ricopro il mio vecchio codice e desidero modificare i nomi delle funzioni in accordo con pep8. Ma voglio mantenere la compatibilità con le vecchie parti del sistema (un refactoring completo del progetto è impossibile perché i nomi delle funzioni fanno parte dell'API e alcuni utenti usano il vecchio codice client).Ridenominazione delle funzioni con conservazione della retrocompatibilità

Esempio semplice, vecchio codice:

def helloFunc(name): 
    print 'hello %s' % name 

Nuovo:

def hello_func(name): 
    print 'hello %s' % name 

Ma entrambe le funzioni dovrebbero funzionare:

>>hello_func('Alex') 
>>'hello Alex' 
>>helloFunc('Alf') 
>>'hello Alf' 

sto pensando:

def helloFunc(name): 
    hello_func(name) 

, ma non mi piace (nel progetto circa 50 funzioni, e sarà un po 'disordinato, penso).

Qual è il modo migliore per farlo (esclusa la duplicazione di origine)? È possibile la creazione di un decoratore universale?

Grazie.

risposta

7

credo che per il momento, la cosa più semplice è quello di creare solo un nuovo riferimento al vecchio oggetto funzione:

def helloFunc(): 
    pass 

hello_func = helloFunc 

Naturalmente, sarebbe probabilmente più leggermente più pulita se si cambiato il nome della funzione reale di hello_func e poi creato l'alias come:

helloFunc = hello_func 

Questo è ancora un po 'disordinato, perché ingombra lo spazio dei nomi del modulo inutilmente. Per aggirare questo, potresti anche avere un sottomodulo che fornisce questi "alias". Quindi, per i tuoi utenti, sarebbe semplice come cambiare import module a import module.submodule as module, ma non ingombrare il tuo spazio dei nomi del modulo.

Probabilmente si potrebbe anche usare inspect a fare qualcosa di simile automagicamente (non testata):

import inspect 
import re 
def underscore_to_camel(modinput,modadd): 
    """ 
     Find all functions in modinput and add them to modadd. 
     In modadd, all the functions will be converted from name_with_underscore 
     to camelCase 
    """ 
    functions = inspect.getmembers(modinput,inspect.isfunction) 
    for f in functions: 
     camel_name = re.sub(r'_.',lambda x: x.group()[1].upper(),f.__name__) 
     setattr(modadd,camel_name,f) 
+0

Oh, come potrei dimenticarlo! Grazie! – vlad

+1

@vlad - Ho aggiunto una funzione che penso aggiungerà automaticamente 'function_with_underscores' dal modulo' modinput' a 'modadd' come' functionWithUnderscores' (ma non funzionerà con le funzioni 'lambda' in quanto non hanno nome ispezionabile (AFAIK) – mgilson

4

È possibile vincolare il proprio oggetto funzione a un altro nome nel namespace del modulo, ad esempio:

def funcOld(a): 
    return a 

func_new = funcOld 
5

Mentre le altre risposte sono sicuramente vere, potrebbe essere utile rinominare la funzione con il nuovo nome e crearne una vecchia che emetta un avviso:

def func_new(a): 
    do_stuff() 

def funcOld(a): 
    import warnings 
    warnings.warn("funcOld should not be called any longer.") 
    return func_new(a) 
2

Dato che la tua domanda suona molto simile alla deprecazione o simile, mi piacerebbe caldamente raccomandare l'uso di decoratori per un codice più pulito. In effetti, qualcuno in un'altra discussione ha già created this for you.

Problemi correlati