重命名功能,保持向后兼容性

时间:2012-08-16 12:24:20

标签: python refactoring

我重构了我的旧代码,并希望根据pep8更改函数的名称。但是我希望保持与系统的旧部分的向后兼容性(项目的完全重构是不可能的,因为函数名称是API的一部分,并且一些用户使用旧的客户端代码)。

简单的例子,旧代码:

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

新:

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

但这两个功能都应该有效:

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

我正在考虑:

def helloFunc(name):
    hello_func(name)

,但我不喜欢它(在项目中约有50个函数,我觉得它看起来很混乱。)

最好的方法是什么(不包括复制资源)?是否有可能创建一个通用装饰器?

感谢。

4 个答案:

答案 0 :(得分:8)

我认为目前最简单的方法是创建一个对旧函数对象的新引用:

def helloFunc():
    pass

hello_func = helloFunc

当然,如果您将实际函数的名称更改为hello_func,然后将别名创建为:

,那么它可能会更加略微更干净
helloFunc = hello_func

这仍然有点乱,因为它不必要地混乱了你的模块名称空间。为了解决这个问题,您还可以使用提供这些“别名”的子模块。然后,对于您的用户来说,就像将import module更改为import module.submodule as module一样简单,但不会使您的模块名称空间混乱。

您甚至可以使用inspect自动执行此类操作(未经测试):

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)

答案 1 :(得分:7)

虽然其他答案肯定是正确的,但将函数重命名为新名称并创建一个发出警告的旧函数可能很有用:

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 :(得分:4)

您可以将函数对象绑定到模块命名空间中的另一个名称,例如:

def funcOld(a):
    return a

func_new = funcOld

答案 3 :(得分:2)

由于您的问题非常类似于弃用或类似问题,因此我强烈建议使用装饰器来实现更清晰的代码。事实上,另一个线程中的某个人已经created this for you