给定路径后的argparse命令行-option [英] argparse command line -option after given path

查看:69
本文介绍了给定路径后的argparse命令行-option的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是python的新手,目前正在尝试使用argparse添加命令行选项.但是,尽管看了各种在线教程并阅读了argparse,但我的代码仍无法正常工作,但我仍然不完全了解它.我的问题是,每当我尝试调用-option时,都会给我一个find.py错误:正则表达式参数:

I'm new to python and currently experimenting using argparse to add command line options. However my code is not working, despite looking at various online tutorials and reading up on argparse I still don't fully understand it. My problem is whenever I try to call my -option it gives me a find.py error: argument regex:

这是我的电话:

./find.py ../Python -name '[0-9]*\.txt'

../Python是我当前目录之后的一个目录,并且具有文件/目录列表.如果没有-name选项,我将打印出带有路径的文件(这可以正常工作),但如果使用-name选项,我想打印出与正则表达式匹配的文件,但是它将不起作用.这是我目前拥有的:

../Python is one directory behind my current one and has a list of files/directories. Without the -name option I print out the files with their path (this works fine) but with the -name option I want to print out files matching the regex but it won't work. Here is what I currently have:

#!/usr/bin/python2.7

import os, sys, argparse,re 
from stat import *

def regex_type(s, pattern=re.compile(r"[a-f0-9A-F]")):
   if not pattern.match(s):
      raise argparse.ArgumentTypeError
   return s

def main():
   direc = sys.argv[1]

   for f in os.listdir(direc):
      pathname = os.path.join(direc, f)
      mode = os.stat(pathname).st_mode
      if S_ISREG(mode):
          print pathname

   parser = argparse.ArgumentParser()
   parser.add_argument(
    '-name', default=[sys.stdin], nargs="*")
   parser.add_argument('regex', type=regex_type) 
   args = parser.parse_args()



if __name__ == '__main__': 

      main()

推荐答案

我调整了您的类型函数以提供更多信息:

I tweaked your type function to be more informative:

def regex_type(s, pattern=re.compile(r"[a-f0-9A-F]")):
   print('regex string', s)
   if not pattern.match(s):
      raise argparse.ArgumentTypeError('pattern not match')
   return s

致电

2104:~/mypy$ python2 stack50072557.py .

我得到:

<director list>
('regex string', '.')
usage: stack50072557.py [-h] [-name [NAME [NAME ...]]] regex
stack50072557.py: error: argument regex: pattern not match

因此,它尝试将脚本名称之后的第一个字符串sys.argv[1]传递给regex_type函数.如果失败,则会发出错误消息和用法.

So it tries to pass sys.argv[1], the first string after the script name, to the regex_type function. If it fails it issues the error message and usage.

好,问题出在..上;我将建立一个目录:

OK, the problem was the ..; I'll make a directory:

2108:~/mypy$ mkdir foo
2136:~/mypy$ python2 stack50072557.py foo
('regex string', 'foo')
Namespace(name=[<open file '<stdin>', mode 'r' at 0x7f3bea2370c0>], regex='foo')

2138:~/mypy$ python2 stack50072557.py foo -name a b c
('regex string', 'foo')
Namespace(name=['a', 'b', 'c'], regex='foo')

'-name'之后的字符串分配给该属性.您的代码中没有任何东西可以测试它们或将它们传递给regex_type函数.只有第一个非标志字符串会这样做.

The strings following '-name' are allocated to that attribute. There's nothing in your code that will test them or pass them through the regex_type function. Only the first non-flag string does that.

最初读取sys.argv[1]不会将其从列表中删除.解析器仍然可以使用它.

Reading sys.argv[1] initially does not remove it from the list. It's still there for use by the parser.

我将设置一个使用store_true --name自变量的解析器和2个位置信息-一个用于dir,另一个用于regex.

I would set up a parser that uses a store_true --name argument, and 2 positionals - one for the dir and the other for regex.

解析后,检查args.name.如果为假,则打印args.dir的内容.如果为true,则对这些内容执行args.regex过滤器. glob可能有用.

After parsing check args.name. If false print the contents of args.dir. If true, perform your args.regex filter on those contents. glob might be useful.

解析器找出您的用户想要什么.您自己的代码对其起作用.特别是对于初学者来说,将两个步骤分开更容易,更干净.

The parser finds out what your user wants. Your own code acts on it. Especially as a beginner, it is easier and cleaner to separate the two steps.

使用:

def parse(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument('-n', '--name', action='store_true')
    parser.add_argument('--dir', default='.')
    parser.add_argument('--regex', default=r"[a-f0-9A-F]")
    args = parser.parse_args(argv)
    print(args)
    return args

def main(argv=None):
    args = parse(argv)
    dirls = os.listdir(args.dir)
    if args.name:
        dirls = [f for f in dirls if re.match(args.regex, f)]
        print(dirls)
    else:
        print(dirls)

我会像这样奔跑

1005:~/mypy$ python stack50072557.py 
Namespace(dir='.', name=False, regex='[a-f0-9A-F]')
['test.npz', 'stack49909128.txt', 'stack49969840.txt', 'stack49824248.py', 'test.h5', 'stack50072557.py', 'stack49963862.npy', 'Mcoo.npz', 'test_attribute.h5', 'stack49969861.py', 'stack49969605.py', 'stack49454474.py', 'Mcsr.npz', 'Mdense.npy', 'stack49859957.txt', 'stack49408644.py', 'Mdok', 'test.mat5', 'stack50012754.py', 'foo', 'test']
1007:~/mypy$ python stack50072557.py -n
Namespace(dir='.', name=True, regex='[a-f0-9A-F]')
['foo']
1007:~/mypy$ python stack50072557.py -n --regex='.*\.txt'
Namespace(dir='.', name=True, regex='.*\\.txt')
['stack49909128.txt', 'stack49969840.txt', 'stack49859957.txt']

和帮助:

1007:~/mypy$ python stack50072557.py -h
usage: stack50072557.py [-h] [-n] [--dir DIR] [--regex REGEX]

optional arguments:
  -h, --help     show this help message and exit
  -n, --name
  --dir DIR
  --regex REGEX


如果我将dir行更改为:


If I change the dir line to:

parser.add_argument('dir', default='.')

现在有帮助

1553:~/mypy$ python stack50072557.py -h
usage: stack50072557.py [-h] [-n] [--regex REGEX] dir

positional arguments:
  dir

optional arguments:
  -h, --help     show this help message and exit
  -n, --name
  --regex REGEX

运行为:

1704:~/mypy$ python stack50072557.py -n
usage: stack50072557.py [-h] [-n] [--regex REGEX] dir
stack50072557.py: error: too few arguments

1705:~/mypy$ python stack50072557.py . -n
Namespace(dir='.', name=True, regex='[a-f0-9A-F]')
['foo']

1705:~/mypy$ python stack50072557.py ../mypy -n --regex='.*\.txt'
Namespace(dir='../mypy', name=True, regex='.*\\.txt')
['stack49909128.txt', 'stack49969840.txt', 'stack49859957.txt']

我收到错误消息是因为它现在需要一个目录,即使它是'.'.

I get the error because it now requires a directory, even it is '.'.

请注意,脚本仍使用:

if __name__ == '__main__': 
    main()

我的main加载dir,并将regex过滤器应用于该名称列表.我的args.dir替换了您的direc.

My main loads the dir, and applies the regex filter to that list of names. My args.dir replaces your direc.

这篇关于给定路径后的argparse命令行-option的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆