argparse 命令行 - 给定路径后的选项 [英] argparse command line -option after given path
问题描述
我是 Python 新手,目前正在试验使用 argparse 添加命令行选项.然而,我的代码不起作用,尽管查看了各种在线教程并阅读了 argparse,但我仍然没有完全理解它.我的问题是每当我尝试调用我的 -option 时,它都会给我一个 find.py 错误:argument regex:
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
.如果为 false,则打印 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
行更改为:
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()
My 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 命令行 - 给定路径后的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!