2012-08-16 20 views
11

我重構了我的舊代碼,並希望根據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個函數,它會看起來很亂,我認爲)。

這樣做的最佳方式是什麼(不包括重複的資源)?是否有可能創建一個普遍的裝飾器?

謝謝。

回答

7

我認爲,就目前而言,最簡單的辦法是隻創建一個新的參照舊函數對象:

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) 
+0

哦,我怎麼能忘記它!謝謝! – vlad 2012-08-16 12:36:50

+1

@vlad - 我已經添加了一個函數,我認爲它會自動從模塊modinput中將'function_with_underscores'添加到'modadd'中作爲'functionWithUnderscores'(但它不會真的與'lambda'函數一起工作,因爲它們沒有可視名稱(AFAIK) – mgilson 2012-08-16 12:42:36

4

您可以將函數對象綁定到另一個名字在你的模塊的名字空間,例如:

def funcOld(a): 
    return a 

func_new = funcOld 
5

雖然其他答案肯定是對的,但將函數重命名爲新名稱並創建一個發出警告的舊函數可能會很有用:

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

由於您的問題聽起來很像是棄用或類似的問題,所以我想強烈建議使用裝飾器來實現更簡潔的代碼。事實上,另一個線程中的某個人已經有created this for you