2012-08-16 10 views
11

Refactorizo ​​mi código anterior y deseo cambiar los nombres de funciones de acuerdo con pep8. Pero quiero mantener la compatibilidad con partes antiguas del sistema (una refacturación completa del proyecto es imposible porque los nombres de las funciones forman parte de la API y algunos usuarios usan el antiguo código de cliente).Renombrado de funciones con preservación de compatibilidad con versiones anteriores

ejemplo simple, código antiguo:

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

Nuevo:

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

Pero ambas funciones deben trabajar:

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

Estoy pensando en:

def helloFunc(name): 
    hello_func(name) 

, pero no me gusta (en el proyecto de unas 50 funciones, y se verá un poco complicado, creo).

¿Cuál es la mejor manera de hacerlo (excluyendo la duplicación del recurso)? ¿Es posible la creación de un decorador universal?

Gracias.

Respuesta

7

creo que, por el momento, lo más fácil es crear sólo una nueva referencia a la función objeto antiguo:

def helloFunc(): 
    pass 

hello_func = helloFunc 

Por supuesto, es probable que sea más ligeramente más limpia si cambiado el nombre de la función real de hello_func y luego creó el alias como:

helloFunc = hello_func 

Esto sigue siendo un poco desordenado, ya que estorba el espacio de nombres del módulo innecesariamente. Para evitarlo, también podría tener un submódulo que proporcione estos "alias". Entonces, para sus usuarios, sería tan simple como cambiar import module a import module.submodule as module, pero no satura el espacio de nombres de su módulo.

Probablemente se podría incluso utilizar inspect a hacer algo como esto automágicamente (no probado):

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, ¿cómo podría olvidarse de él! ¡Gracias! – vlad

+1

@vlad - ¡Tengo una función que creo que va a añadir automáticamente 'function_with_underscores' de módulo' 'modinput' en modadd' como' functionWithUnderscores' (pero no va a trabajar realmente con 'funciones lambda' ya que no tienen nombre inspeccionable (AFAIK) – mgilson

4

puede enlazar su objeto de función a otro nombre de espacio de nombres del módulo, por ejemplo:

def funcOld(a): 
    return a 

func_new = funcOld 
5

mientras que las otras respuestas son sin duda cierto, podría ser útil para cambiar el nombre de la función para el nuevo nombre y crear una vieja que emite una advertencia:

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

medida que su pregunta suena muy parecido a depreciación o similares, me gustaría recomendar encarecidamente el uso de decoradores de código más limpio. De hecho, alguien en otro hilo ya tiene created this for you.

Cuestiones relacionadas