2014-03-28 37 views
0

我有一些修飾器函數在執行它們裝飾的函數之前/之後執行其他代碼。我想要做的是動態地將附加行爲記錄到裝飾函數的文檔字符串中。我已保留functools.wrap的名稱和此類屬性。從修飾器修改文檔字符串,同時保留格式化

這裏是想我做一個簡單的例子:

numbers_added = [] 

def record_number(func): 
    decorator_doc = '''\nRecord added numbers in numbers_added''' 
    def add_and_record(n): 
     r = func(n) 
     if r is not False: 
      numbers_added.append(n) 
     return r 
    add_and_record.__doc__ = func.__doc__ + decorator_doc 
    return add_and_record 

@record_number 
def add2_to_even(n): 
    '''Add 2 to an even number, `n`. 

     If n is not even, return False''' 
    if n % 2 == 0: 
     return n + 2 
    return False 

現在,這裏的一切的偉大工程和文檔字符串更新成功,那麼什麼是我的問題嗎?如果您看一下help(add2_to_even),您會看到文檔字符串的第二行沒有正確格式化。通常任何領先的縮進都會被刪除,但在這種情況下會被保留。我能做些什麼來保持預期的格式?

注意:在Python Docstring慣例(PEP 257)中有一個算法實現,但我寧願不使用類似的東西並重新實現核心功能。

回答

0

inspect.cleandoc函數實質上實現了PEP 257中的trim算法。您可以使用它來進行修整。

由於您的新文檔字符串沒有縮進,爲了將其與舊的文檔字符串合併,您需要擺脫舊縮進。所以你可能需要做的是修剪現有的文檔字符串,然後附加你的新文檔。也就是說,改變的record_number到下一個到最後一行:

add_and_record.__doc__ = inspect.cleandoc(func.__doc__) + decorator_doc 

這讓我試試你的榜樣正確的結果,但我不知道肯定做是否會有優勢的情況下它爲具有更復雜格式的文檔提供奇怪的輸出。

+0

我按照原來的代碼給了它一個代碼,它給了我相同的結果。但是,由於某種原因,我決定嘗試使用兩個具有相同初始縮進的文檔,並給出了預期的結果。此外,在沒有cleandoc的情況下嘗試它,但使用新的縮進修復程序,它仍然會給出預期的結果。因此,我現在有一些工作,儘管它還不完全理想,但如果沒有更好的解決方案出現,我可以接受它。 –

+0

@JohnHill:你將不得不在現有的文檔字符串上執行'cleandoc',然後追加你的新文檔。看到我編輯的答案。 – BrenBarn