【问题标题】:command line argument followed by argparse option命令行参数后跟 argparse 选项
【发布时间】:2023-03-13 19:07:02
【问题描述】:

我是 python 新手,目前正在玩 argpase。我正在尝试使用作为命令行参数给出的目录路径调用一个函数,后跟一个 argparse 选项(-name)和一个正则表达式,它遍历目录中的所有文件并将所有匹配项吐出到正则表达式中:

./find.py ../seek -name '[a-z]*\.txt'

但是,我收到了一个看起来像

的错误

usage: find.py [-h] [--path PATH] [-name] [--regex REGEX] find.py: error: unrecognized arguments: . . / s e e k / p r o g r a m . c

如果没有 -name,它只会打印路径内的所有文件。

这是我目前所拥有的:

#!/usr/bin/python2.7

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

def parse(argv=None):
   parser = argparse.ArgumentParser()
   parser.add_argument('--path', help='path of directory', action='store')
   parser.add_argument('-name', '--name', action='store_true')
   parser.add_argument('--regex', default=r"[a-z0-9A-Z]")
   args = parser.parse_args(argv)
   print(args)
   return args

def main(argv=None):

   direc = sys.argv[1]
   files = []

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

      if S_ISREG(mode):  
         args = parse(pathname)      
         if args.name:  
            dirls = [re.match(args.regex, pathname)]
            print(dirls)
         else:
            print pathname

if __name__ == '__main__':main() 

有什么想法吗?

【问题讨论】:

  • 通常parse_args 使用sys.argv[1:]。在这里,您将其替换为 pathname(通过 argv)。 pathname 是一个字符串,parse_args 将其转换为 list,例如list(pathname)。这就是错误消息所抱怨的内容。
  • parse 应该在f 循环之外调用一次。
  • parse 中的argv 参数(复制自我之前的回答)允许我们提供字符串的测试列表。但如果是默认的None,则使用sys.argv[1:]。这个解析器期望一个目录被提供为'--path '。我们可以将其更改为不带“--path”标志的位置参数。

标签: python python-2.7 argparse


【解决方案1】:

参数解析器路径示例:添加了自定义处理程序的不同类型的参数。对于此处的路径,您可以传递 '-path' 后跟路径值作为参数

import os
import argparse
from datetime import datetime


def parse_arguments():
    parser = argparse.ArgumentParser(description='Process command line arguments.')
    parser.add_argument('-path', type=dir_path)
    parser.add_argument('-e', '--yearly', nargs = '*', help='yearly date', type=date_year)
    parser.add_argument('-a', '--monthly', nargs = '*',help='monthly date', type=date_month)

    return parser.parse_args()


def dir_path(path):
    if os.path.isdir(path):
    return path
    else:
    raise argparse.ArgumentTypeError(f"readable_dir:{path} is not a valid path")


def date_year(date):
    if not date:
    return

    try:
    return datetime.strptime(date, '%Y')
    except ValueError:
    raise argparse.ArgumentTypeError(f"Given Date({date}) not valid")


def date_month(date):
    if not date:
    return

    try:
    return datetime.strptime(date, '%Y/%m')
    except ValueError:
    raise argparse.ArgumentTypeError(f"Given Date({date}) not valid")


def main():
    parsed_args = parse_arguments()

if __name__ == "__main__":
main()

【讨论】:

    【解决方案2】:

    为了让您的程序运行,您需要一个路径。因此,--path 选项必须带一个参数。修改您的parse() 函数以更改行

    parser.add_argument('--path', help='path of directory', action='store')
    

    parser.add_argument('--path', help='path of directory', action='store', required=True)
    

    您只需致电parse_args() 一次。将parse() 调用移至循环顶部。

    你不需要这样做

    direc = sys.argv[1]
    

    如果您使用的是argparse

    re.match() 返回一个match object,这可能不是您想要打印的。

    您可能想看看match() versus search()

    match() 函数仅检查 RE 是否在字符串开头匹配,而 search() 将向前扫描字符串以查找匹配项。

    如果你想打印匹配正则表达式的文件名,你可以这样做

      if S_ISREG(mode):  
         #args = parse(pathname)      
         if args.name:  
            #dirls = re.match(args.regex, pathname)
            dirls = re.search(args.regex, pathname)
            if( dirls ):
               print(pathname)
         else:
            print pathname
    

    所以main() 应该是这样的

    def main(argv=None):
        args = parse(sys.argv[1:])
        print(args)
        #direc = sys.argv[1]
        direc = args.path
        files = []
    
        for f in os.listdir(direc):
          pathname = os.path.join(direc, f)
          mode = os.stat(pathname).st_mode
    
        if S_ISREG(mode):  
           #args = parse(pathname)      
           if args.name:  
              #dirls = re.match(args.regex, pathname)
              dirls = re.search(args.regex, pathname)
              if( dirls ):
                 print(pathname)
           else:
              print pathname
    

    为了指定匹配文件名的正则表达式,您必须使用--regex 选项指定正则表达式。默认情况下,您已使其匹配只有数字和(英文)字母的名称。

    ./find.py --path ../seek -name --regex [a-z]\*.txt
    

    ./find.py --path ../seek -name --regex '[a-z]*.txt'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-04
      • 2023-04-03
      • 2016-05-02
      • 2013-09-13
      • 1970-01-01
      • 2012-12-13
      • 2013-11-11
      相关资源
      最近更新 更多