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

vla*_*lad 11 python refactoring

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

简单的例子,旧代码:

def helloFunc(name):
    print 'hello %s' % name
Run Code Online (Sandbox Code Playgroud)

新:

def hello_func(name):
    print 'hello %s' % name
Run Code Online (Sandbox Code Playgroud)

但这两个功能应该有效:

>>hello_func('Alex')
>>'hello Alex'
>>helloFunc('Alf')
>>'hello Alf'
Run Code Online (Sandbox Code Playgroud)

我在考虑:

def helloFunc(name):
    hello_func(name)
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢.

mgi*_*son 9

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

def helloFunc():
    pass

hello_func = helloFunc
Run Code Online (Sandbox Code Playgroud)

当然,它很可能是更轻微,如果你改变实际功能的名称更干净hello_func,然后创建的别名为:

helloFunc = hello_func
Run Code Online (Sandbox Code Playgroud)

这仍然有点凌乱,因为它不必要地混乱了你的模块命名空间.为了解决这个问题,您还可以使用提供这些"别名"的子模块.然后,对于您的用户来说,它就像更改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)
Run Code Online (Sandbox Code Playgroud)


glg*_*lgl 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)
Run Code Online (Sandbox Code Playgroud)

  • 更好的是,使用warnings.warn('description',DeprecationWarning)`明确指出此调用转换已被弃用 (2认同)