argparse 命令行 -选项在给定路径之后



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

这是我的电话:

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

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

#!/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()

我调整了你的类型函数,使其信息量更大:

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函数。 如果失败,它会发出错误消息和使用情况。

好的,问题是..;我将创建一个目录:

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 函数传递它们。 只有第一个非标志字符串才能做到这一点。

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

我会设置一个使用 store_true --name 参数和 2 个位置的解析器 - 一个用于dir,另一个用于regex

解析后检查args.name . 如果错误打印args.dir的内容。 如果为 true,请对这些内容执行args.regex筛选。 glob可能有用。

解析器找出用户想要什么。 你自己的代码作用于它。 特别是作为初学者,将这两个步骤分开更容易,更干净。


跟:

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行更改为:

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']

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

请注意,该脚本仍使用:

if __name__ == '__main__': 
    main()

我的main加载dir,并将regex过滤器应用于该名称列表。 我的args.dir取代了你的direc.

最新更新