尝试使用 argparse 和 sys.argv 而无需在每个运行时都使用 sys.argv

Trying to use argparse and sys.argv without sys.argv needing to be used each runtime

在我正在编写的脚本中,我使用 argparse 作为主要参数(用于 --help、--todo 等),但尝试使用 sys.argv 来获取文件名作为 --add 的第三个参数给出。我正在使用这个:

def parseargs():
    parser = argparse.ArgumentParser(add_help=False)

    parser.add_argument("--help", help="Print argument usage", action="store_true")
    parser.add_argument("--memo", help="Read memo file", action="store_true")
    parser.add_argument("--todo", help="Read TODO file", action="store_true")
    parser.add_argument("--trackedfiles", help="Read tracked files list", action="store_true")

    parser.add_argument("--add", help="Add a file to trackedfiles", action="store_true")
    parser.add_argument("--edit", help="Edit file in .wpm_data with editor", action="store_true")
    parser.add_argument("--newdir", help="Create a new directory to initialize user-data", action="store_true")

    parser.add_argument("file")

    p_args = parser.parse_args()

    if p_args.help:
        printargs()
        sys.exit()

    if p_args.memo:
        print_memo()
        sys.exit()

    if p_args.todo:
        print_todo()
        sys.exit()

    if p_args.trackedfiles:
        print_trackedfiles()
        sys.exit()

    if p_args.add: # this is were I'm stumpped
        if p_args.file == sys.argv[2]:
            givenfile = p_args.file
        else:
            pass

        print("[!]\t", givenfile, "to be added to trackedfiles")

        sys.exit()

它是这样工作的:

./main.py --add textfile.txt
[!]  textfile.txt to be added to trackedfiles

但是当像 --help 这样使用不同的参数时,需要为给定的文件使用第三个参数

./main.py --help            
usage: main.py [--help] [--memo] [--todo] [--trackedfiles] [--add] [--edit]
               [--newdir]
               file
    main.py: error: the following arguments are required: file

我如何使用 argparse 和 sys.argv 分开,sys.argv 不需要经常使用,所以它只能在需要它的函数是 运行 时调用?

你做错了。下面是一些示例,可帮助您了解如何使用 argparse。标志不是布尔值,它们可以有值。

import argparse
parser = argparse.ArgumentParser(description="This program does cool things.")

parser.add_argument("--add", help="Add a file to trackedfiles")
parser.add_argument("--dell", help="Delete file")
parser.add_argument("--copy", help="Copy file")
p_args = parser.parse_args()

print "Add-->.", p_args.add
print "Dell->.", p_args.dell  #del is reserved word so we use dell
print "Copy->.", p_args.copy

这是用法。

$ python p.py --dell file1.txt --copy file2.txt --add file3.txt
Add-->. file3.txt
Dell->. file1.txt
Copy->. file2.txt

希望对您有所帮助。

我有点猜测你想做什么,但这是我的建议:

def parseargs():
    parser = argparse.ArgumentParser()
    # use the normal help, unless your `printargs` is much better
    parser.add_argument("--memo", help="Read memo file", action="store_true")
    parser.add_argument("--todo", help="Read TODO file", action="store_true")
    parser.add_argument("--trackedfiles", help="Read tracked files list", action="store_true")

    parser.add_argument("--add", help="Add a file to trackedfiles")  # takes a filename argument
    parser.add_argument("--edit", help="Edit file in .wpm_data with editor")  # takes a filename argument
    parser.add_argument("--newdir", help="Create a new directory to initialize user-data")  # takes a directory name argument

    p_args = parser.parse_args()

    if p_args.memo:
        print_memo()
    eliif p_args.todo:
        print_todo()
    elif p_args.trackedfiles:
        print_trackedfiles()
    elif p_args.add:  # could be 'if is not None:'
        add_file(p_args.add)
    elif p_args.edit:
        ....

所以最大的变化是使 'filename' 成为“--add”或“--edit”标志的参数,而不是位置参数。如果它是必需的位置参数,如果您使用 --memo.

等参数省略它,您将收到一条错误消息

或者 file 可以是 nargs='?' 位置。

您也可以将其设置为子解析器案例,其中 memo,todo,trackfiles,add,etc 都是 'commands'。其中一些子解析器将采用 'file' 参数,而另一些则不会。我希望其他人会对此进行详细说明。

有一个很好的 subparsers 答案。


非子解析器替代方案:

parser = argparse.ArgumentParser()
parser.add_argument('cmd', 
     choices=['memo','todo','trackfiles','add','edit','newdir'],
     help='action to take')
parser.add_argument('name',nargs='?',help='file or dir name')
args = parser.parse_args()
if args.cmd in ['memo']:
   print_memo()
elif args.cmd in ['todo']:
   ...
elif args.cmd in ['add']:
   add_file(args.name)
elif ...

这应该接受像 prog.py memoprog.py add myfile 这样的命令。 add_file(afilename) 如果它的参数是 None 或一个错误的文件名,它应该做一些聪明的事情。

如果您想在每次通话中接受不止一个 'commands',那么我们需要进行一些更改。