2012-08-16 13 views
11

Ich refactor mein alter Code und möchte die Namen der Funktionen in Übereinstimmung mit pep8 ändern. Aber ich möchte Abwärtskompatibilität mit alten Teilen des Systems aufrechterhalten (eine vollständige Umgestaltung des Projekts ist unmöglich, weil Funktionsnamen Teil der API sind und einige Benutzer den alten Client-Code verwenden).Umbenennen von Funktionen unter Beibehaltung der Abwärtskompatibilität

Einfaches Beispiel, alten Code:

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

Neu:

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

Aber beide Funktionen funktionieren sollte:

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

Ich denke an:

def helloFunc(name): 
    hello_func(name) 

, aber ich mag es nicht (im Projekt über 50 Funktionen, und es wird ein chaotisch aussehen, denke ich).

Was ist der beste Weg (abgesehen von der Duplizierung der Quelle)? Ist es möglich, einen universellen Dekorateur zu kreieren?

Danke.

Antwort

7

Ich denke, dass für die Zeit ist, die einfachste Sache ist, einfach einen neuen Verweis auf die alte Funktion Objekt zu erstellen:

def helloFunc(): 
    pass 

hello_func = helloFunc 

Natürlich wäre es wahrscheinlich mehr leicht mehr sauber sein, wenn Sie änderte den Namen der eigentlichen Funktion hello_func und erstellt dann den Alias ​​als:

helloFunc = hello_func 

Dies ist unnötig noch ein wenig chaotisch, weil es clutters Ihr Modul-Namespace. Um das zu umgehen, könnte man auch ein Submodul haben, das diese "Aliase" bereitstellt. Dann wäre es für Ihre Benutzer einfach, import module zu import module.submodule as module zu ändern, aber Sie verstopfen Ihren Modulnamespace nicht.

Sie könnten wahrscheinlich sogar inspect verwenden so etwas wie dieses automagically (ungetestet) zu tun:

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, wie könnte ich das vergessen! Vielen Dank! – vlad

+1

@vlad - Ich habe eine Funktion hinzugefügt, die automatisch 'function_with_underscores' aus dem Modul 'modinput' in' modadd' als 'functionWithUnderscores' hinzufügt (aber es wird nicht wirklich mit' lambda' funktionieren, da sie keine haben kontrollierbarer Name (AFAIK) – mgilson

4

Sie binden Ihre Funktion Objekt auf einen anderen Namen im Namensraum Ihres Moduls, zB:

def funcOld(a): 
    return a 

func_new = funcOld 
5

Während die anderen Antworten definitiv wahr sind, könnte es nützlich sein, die Funktion in den neuen Namen umzubenennen und einen alten zu erstellen, der eine Warnung ausgibt:

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

Da Ihre Frage sehr nach Abwertung oder ähnlichem klingt, empfehle ich dringend die Verwendung von Dekoratoren für saubereren Code. Tatsächlich hat jemand in einem anderen Thread bereits created this for you.

Verwandte Themen