python3 argparse自动完成失败

时间:2017-03-30 06:10:13

标签: bash python-3.x argparse

当我在python3中使用arparse时,我发现了一些奇怪的东西。

#!/usr/bin/env python3

import argparse

def create_parser():
    p = argparse.ArgumentParser(add_help=True)
    p.add_argument('-i', help='i parameter', required=True)
    p.add_argument('-m', help='m parameter', required=True)
    return p

if __name__ == '__main__':
    p = create_parser()
    n = p.parse_args()
    print(n)

当我尝试使用

启动时
python3 ./script.py -i ./some_folder/some_file -m ./

bash自动完成功能使用'-i'参数,但无法使用'-m'。例如,如果我将'-m'重命名为'-me',那么一切都很好。

在bash中,我尝试使用'-m'参数启动其他命令,但它不能仅用于argparse。这里哪里有错误?

1 个答案:

答案 0 :(得分:4)

这里发生的事情是python3命令的自动完成开始:

$ complete | grep python
complete -F _python python2
complete -F _python python3
complete -F _python python

处理它的函数_python应如下所示:

$ type _python
_python is a function
_python () 
{ 
    local cur prev words cword;
    _init_completion || return;
    case $prev in 
        -'?' | -h | --help | -V | --version | -c)
            return 0
        ;;
        -m)
            _python_modules "$1";
            return 0
        ;;
        -Q)
            COMPREPLY=($( compgen -W "old new warn warnall" -- "$cur" ));
            return 0
        ;;
        -W)
            COMPREPLY=($( compgen -W "ignore default all module once error"                 -- "$cur" ));
            return 0
        ;;
        !(?(*/)python*([0-9.])|-?))
            [[ $cword -lt 2 || ${words[cword-2]} != -@(Q|W) ]] && _filedir
        ;;
    esac;
    local i;
    for ((i=0; i < ${#words[@]}-1; i++ ))
    do
        if [[ ${words[i]} == -c ]]; then
            _filedir;
        fi;
    done;
    if [[ "$cur" != -* ]]; then
        _filedir 'py?([co])';
    else
        COMPREPLY=($( compgen -W '$( _parse_help "$1" -h )' -- "$cur" ));
    fi;
    return 0
}

完成函数将-m标志视为与python或脚本的参数相同,因此它会尝试使用模块名称列表来完成。

解决此问题的一种方法是使用不会触发完成的python3命令的别名,例如:

$ alias py3=python3

为了保持这种持久性,你可以把它放在你的~/.bashrc中。然后你可以使用

$ py3 ./script.py -i ./some_folder/some_file -m ./[TAB]

将使用文件名完成。

或者将-m标志重命名为其他内容。