我重构了我的旧代码,并希望根据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个函数,我觉得它看起来很混乱。)
最好的方法是什么(不包括复制资源)?是否有可能创建一个通用装饰器?
感谢。
答案 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。