parse_args all .png files from a parser argument

喜欢而已 提交于 2020-01-06 06:28:30

问题


I would like to get a arg.pics which returns something like ['pic1.png', 'pic2.png', 'pic3.png'] (to arbitrarily parse all files of .png format) after running the following (test.py):

import argparse
import os

def parser_arg():
    par = argparse.ArgumentParser()
    parser = par.add_argument_group('pictures')
    parser.add_argument("-p", "--pics", nargs="+", help="picture files", required=True)
    arguments = par.parse_args()
    return arguments

args = parser_arg()

And upon running the script via command line, and inputting

python test.py -p ../User/Desktop/Data/*.png

then args.pics returns ['../User/Desktop/Data/*.png'] instead..

Am I using the right approach? I heard using *.png will be expanded into the .png files once inputted but it doesn't seem to be the case on my end.

Edits: I'm using Anaconda Prompt on Windows 10 if it helps.


回答1:


There are a couple of things that could be going on. One possibility is that ../User/Desktop/Data/*.png does not match any files, so does not get expanded. This would happen on a UNIX-like shell only (or PowerShell I suppose). The other possibility is that you are using cmd.exe on Windows, which simply does not do wildcard expansion at all. Given that you are using Anaconda prompt on Windows, I would lean towards the latter possibility as the explanation.

Since you are looking for a list of all the PNGs in a folder, you don't need to rely on the shell at all. There are lots of ways of doing the same thing in Python, with and without integrating in argparse.

Let's start by implementing the listing functionality. Given a directory, here are some ways to get a list of all the PNGs in it:

  1. Use glob.glob (recommended option). This can either recurse into subdirectories or not, depending on what you want:

    mydir = '../User/Desktop/Data/'
    pngs = glob.glob(os.path.join(mydir, '*.png'))
    

    To recurse into subfolders, just add the recursive=True keyword-only option.

  2. Use os.walk. This is much more flexible (and therefore requires more work), but also lets you have recursive or non-recursive solutions:

    mydir = '../User/Desktop/Data/'
    pngs = []
    for path, dirs, files in os.walk(mydir):
        pngs.extend(f for f in files if f.lower().endswith('.png'))
        del dirs[:]
    

    To enable recursion, just delete the line del dirs[:], which suppresses subdirectory search.

  3. A related method that is always non-recursive, is to use os.listdir, which is Pythons rough equivalent to ls or dir commands:

    mydir = '../User/Desktop/Data/'
    pngs = [f for f in os.listdir(mydir) if f.lower().endswith('.png')]
    

    This version does not check if something is actually a file. It assumes you don't have folder names ending in .png.

Let's say you've picked one of these methods and created a function that accepts a folder and returns a file list:

def list_pngs(directory):
    return glob.glob(os.path.join(directory, '*.png'))

Now that you know how to list files in a folder, you can easily plug this into argparse at any level. Here are a couple of examples:

  1. Just get all your directories from the argument and list them out afterwards:

    parser.add_argument("-p", "--pics", action='store', help="picture files", required=True)
    

    Once you've processed the arguments:

    print(list_pngs(args.pics))
    
  2. Integrate directly into argparse with the type argument:

    parser.add_argument("-p", "--pics", action='store', type=list_pngs, help="picture files", required=True)
    

    Now you can use the argument directly, since it will be converted into a list directly:

    print(args.pics)
    



回答2:


Your approach is correct. However, your script will only receive the expanded list of files as parameters if your shell supports globbing and the pattern actually matches any files. Otherwise, it will be the pattern itself in most cases.

The Anaconda Command Prompt uses cmd.exe by default, which doesn't support wildcard expansion. You could use PowerShell instead, which does understand wildcards. Alternatively, you can do the expansion in your application as described in Mad Physicist's answer.



来源:https://stackoverflow.com/questions/52426694/parse-args-all-png-files-from-a-parser-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!