2016-09-20 48 views
7

我使用優秀的Python Click庫來處理我的工具中的命令行選項。下面是我的代碼的簡化版本(完整的腳本here):Python Click:自定義錯誤消息

@click.command(
    context_settings = dict(help_option_names = ['-h', '--help']) 
) 
@click.argument('analysis_dir', 
       type = click.Path(exists=True), 
       nargs = -1, 
       required = True, 
       metavar = "<analysis directory>" 
) 

def mytool(analysis_dir): 
    """ Do stuff """ 

if __name__ == "__main__": 
    mytool() 

如果有人運行命令不帶任何標誌,他們得到的默認點擊錯誤消息:

$ mytool 

Usage: mytool [OPTIONS] <analysis directory> 

Error: Missing argument "analysis_dir". 

這是不錯,但我'很想告訴(非常)新手用戶,通過使用幫助標誌可以獲得更多的幫助。換句話說,當命令無效時,向錯誤消息添加自定義句子,告訴人們嘗試mytool --help以獲取更多信息。

有沒有簡單的方法來做到這一點?我知道我可以刪除required屬性,並在主函數中處理這個邏輯,但是對於這樣一個小小的添加,這會讓人覺得很不方便。

+0

我有完全相同的問題。如果發生錯誤,我想要自動打印幫助,或者至少告訴用戶如何打印幫助。否則,我們必須假設每個使用我們工具的人都熟悉基於unix的思維。我喜歡點擊迄今,但沮喪,這個問題還沒有得到回答,因爲我想要的東西,這將有助於建立新手可以輕鬆使用的工具。 – user1677663

+0

剛剛發現這,這可能是一個解決方案:http://stackoverflow.com/questions/35642202/python-click-return-the-helper-menu – user1677663

+0

不,沒有工作。 – user1677663

回答

3

python單擊中大多數錯誤的消息構造由UsageError類的show方法處理:click.exceptions.UsageError.show

因此,如果您重新定義此方法,您將能夠創建自己的自定義錯誤消息。下面是滿足此SO question其中追加的幫助菜單中的任何錯誤消息的定製的例子:

def modify_usage_error(main_command): 
    ''' 
     a method to append the help menu to an usage error 

    :param main_command: top-level group or command object constructed by click wrapper 
    :return: None 
    ''' 

    from click._compat import get_text_stderr 
    from click.utils import echo 
    def show(self, file=None): 
     import sys 
     if file is None: 
      file = get_text_stderr() 
     color = None 
     if self.ctx is not None: 
      color = self.ctx.color 
      echo(self.ctx.get_usage() + '\n', file=file, color=color) 
     echo('Error: %s\n' % self.format_message(), file=file, color=color) 
     sys.argv = [sys.argv[0]] 
     main_command() 

    click.exceptions.UsageError.show = show 

一旦你定義你的主要命令,就可以運行修改腳本:

import click 
@click.group() 
def cli(): 
    pass 

modify_usage_error(cli) 

我還沒有探究是否有使用錯誤以外的ClickException的運行時調用。如果存在,那麼您可能需要修改自定義錯誤處理程序,以便在添加行click.exceptions.ClickException.show = show之前首先檢查ctx是否屬於屬性,因爲它在初始化時不會顯示ClickException是由ctx提供的。

+0

太棒了,謝謝RJ!這對一個例外完美起作用 - 我不得不將最後的函數調用移到'main_command()',因爲這會導致遞歸錯誤。 – tallphil

+0

這感覺很好! https://github.com/ewels/MultiQC/commit/62cc60我已經有了一個低級別的煩惱,因爲無法在7個月內完成這個任務!再次感謝! – tallphil