2012-08-16 17 views
11

I refactor mój stary kod i chcę zmienić nazwy funkcji zgodnie z pep8. Ale chcę zachować wsteczną kompatybilność ze starymi częściami systemu (całkowite zreorganizowanie projektu jest niemożliwe, ponieważ nazwy funkcji są częścią API, a niektórzy użytkownicy używają starego kodu klienta).Zmiana nazwy funkcji z zachowaniem kompatybilności wstecznej

Prosty przykład, stary kod:

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

Nowość:

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

Ale obie funkcje powinny działać:

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

myślę o:

def helloFunc(name): 
    hello_func(name) 

, ale nie podoba mi się to (w projekcie około 50 funkcji, a będzie to wyglądać niechlujnie, jak sądzę).

Jaki jest najlepszy sposób na to (z wyłączeniem powielania zasobów)? Czy możliwe jest stworzenie jakiegoś uniwersalnego dekoratora?

Dzięki.

Odpowiedz

7

myślę, że w chwili obecnej, najłatwiej jest po prostu utworzyć nowe odniesienie do starego obiektu funkcji:

def helloFunc(): 
    pass 

hello_func = helloFunc 

Oczywiście, będzie to prawdopodobnie bardziej nieznacznie bardziej czysty, jeśli was zmienił nazwę rzeczywistej funkcji do hello_func a następnie utworzony alias jako:

helloFunc = hello_func 

jest jeszcze trochę brudny bo to zaśmiecanie przestrzeni nazw modułu niepotrzebnie. Aby obejść ten problem, można również mieć moduł częściowy, który udostępnia te "aliasy". Następnie dla użytkowników byłoby tak proste, jak zmiana import module na import module.submodule as module, ale nie zaśmiecasz przestrzeni nazw modułu.

prawdopodobnie można nawet użyć inspect zrobić coś tak automagicznie (niesprawdzone):

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

Och, jak mogłem o tym zapomnieć! Dzięki! – vlad

+1

@vlad - Dodałem funkcję, która moim zdaniem automatycznie doda 'function_with_underscores' z modułu' modinput' na 'modadd' jako' functionWithUnderscores' (ale nie zadziała tak naprawdę z funkcjami 'lambda', ponieważ nie mają sprawdzalna nazwa (AFAIK) – mgilson

4

Można powiązać swój obiekt funkcji do innej nazwy w przestrzeni nazw modułu jest, na przykład:

def funcOld(a): 
    return a 

func_new = funcOld 
5

Podczas gdy pozostałe odpowiedzi są z pewnością prawdziwe, może być przydatna zmiana nazwy funkcji na nową nazwę i utworzenie starej, która będzie generować ostrzeżenie:

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

W związku z tym, że twoje pytanie brzmi bardzo podobnie do przestarzałego lub podobnego, chciałbym gorąco polecić użycie dekoratorów do czystszego kodu. W rzeczywistości ktoś w innym wątku ma już numer created this for you.

Powiązane problemy