Trying to use argparse and sys.argv without sys.argv which needs to be used in every runtime

In a script I am writing, I am using argparse for the main arguments (for -help, --todo, etc.), but trying to use sys.argv to get the filename specified as the third argument for --add. I used this:

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()

      

Which works like this:

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

      

But when a different argument would be used like --help

for a given file

the third argument must be used,
./main.py --help            
usage: main.py [--help] [--memo] [--todo] [--trackedfiles] [--add] [--edit]
               [--newdir]
               file
    main.py: error: the following arguments are required: file

      

How can I separate the use of argparse and sys.argv, since sys.argv doesn't need to be used all the time, so it can only be called when a function that needs it is executing?

+3


source to share


2 answers


You are doing it wrong. Here are some examples to help you understand how to use argparse. Flags are not boolean, they can have values.

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

      

And here is the use.



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

      

Hope this helps.

+2


source


I'm guessing what you want to do, but here's my suggestion:

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:
        ....

      

So the big change is making "filename" an argument to the "-add" or "-edit" flag, not a positional one. If it is a required positional argument, you will get an error if you omit it using type arguments --memo

.

Alternatively, it file

could be a position nargs='?'

.

You can also set this as an example of sub-guarantees where memo,todo,trackfiles,add,etc

are all "commands". Some of these subparameters will accept a file argument, others will not. I expect someone else to discuss this.

How do I check for a specific sub-parameter? has a good answer subparsers

.




An alternative to non-subscriptions:

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 ...

      

This should take the type of command prog.py memo

, prog.py add myfile

. add_file(afilename)

should do something smart if its an argument None

or a bad filename.

If you want to accept more than one of these "commands" as a challenge, we will need to make some changes.

0


source







All Articles