草庐IT

python中argparse模块的用法

Python学习 2023-03-28 原文

argparse 模块

一个可执行文件或者脚本都可以接收参数。

$ ls -l /etc
/etc 是位置参数

-l 是短选项

如何把这些参数传递给程序呢?
从3.2开始Python提供了功能强大的参数分析的模块argparse。

1.参数分类

参数分为:

  • 位置参数,参数放在那里,就要对应一个参数位置。例如/etc就是对应一个参数位置。
  • 选项参数,必须通过前面是 - 的短选项或者 -- 的长选项,然后后面的才算该选项的参数,当然选项后面也可以没有参数。

上例中,/etc对应的是位置参数,-l是选项参数。

ls -alh src

2.基本解析

先来一段最简单的程序

import argparse
parser = argparse.ArgumentParser() # 获得一个参数解析器
args = parser.parse_args()  # 分析参数

parser.print_help()  # 打印帮助

运行结果

$ python test.py -h
usage: test1.py [-h]
    
optional arguments:

-h, --help show this help message and exit

argparse不仅仅做了参数的定义和解析,还自动帮助生成了帮助信息。尤其是usage,可以看到现在定义的参数是否是自己想要的。

3.解析器的参数

参数名称 说明
prog 程序的名字,缺省使用 sys.argv[0] 的 basename
add_help 自动为解析器增加 -h 和 --help 选项,默认为True
description 为程序功能添加描述
  • parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
$ python test.py --help
usage: ls [-h]
list directory contents
optional arguments:
  -h, --help show this help message and exit

4.位置参数解析

ls 基本功能应该解决目录内容的打印。
打印的时候应该指定目录路径,需要位置参数。

import argparse
 
# 获得一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list 
directory contents')
parser.add_argument('path')
                                 
args = parser.parse_args()  # 分析参数
parser.print_help()  # 打印帮助
                                 
# 运行结果,出现了错误,提示需要输入path对应的位置参数
usage: ls [-h] path

ls: error: the following arguments are required: path

程序定义为:

ls [-h] path
-h为帮助选项,可有可无
path为位置参数,必须提供

传参

parse_args(args=None, namespace=None)

args 参数列表,一个可迭代对象。内部会把可迭代对象转换成list。如果为None则使用命令行传入参数,非None则使用args参数的可迭代对象。

import argparse
 
# 获得一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list 
directory contents')
parser.add_argument('path') # 位置参数
args = parser.parse_args(('/etc',))  # 分析参数,同时传入可迭代的参数
print(args, args.path) # 打印名词空间中收集的参数
parser.print_help()  # 打印帮助

运行结果

Namespace(path='/etc') /etc
usage: ls [-h] path
                                 
list directory contents
                                 
positional arguments:
  path
                                 
optional arguments:

  -h, --help  show this help message and exit

Namespace(path='/etc')里面的path参数存储在了一个Namespace对象内的属性上,可以通过
Namespace对象属性来访问,例如args.path

非必须位置参数

上面的代码必须输入位置参数,否则会报错。

usage: ls [-h] path

ls: error: the following arguments are required: path

但有时候,ls命令不输入任何路径的话就表示列出当前目录的文件列表。

import argparse
# 获得一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list 
directory contents')
parser.add_argument('path', nargs='?', default='.', help="path help") # 位置
参数,可有可无,缺省值,帮助
args = parser.parse_args()  # 分析参数,同时传入可迭代的参数
print(args) # 打印名词空间中收集的参数
parser.print_help()  # 打印帮助
# 运行结果
Namespace(path='.')
usage: ls [-h] [path]
list directory contents
positional arguments:
  path        path help
optional arguments:

  -h, --help  show this help message and exit

可以看出path也变成可选的位置参数,没有提供就使用默认值 .点号 表示当前路径。

help 表示帮助文档中这个参数的描述
nargs 表示这个参数接收结果参数

  • ? 表示可有可无
  • +表示至少一个
  • *可以任意个
  • 数字表示必须是指定数目个

default 表示如果不提供该参数,就使用这个值。一般和?、*配合,因为它们都可以不提供位置参数,不提供就用缺省值

5.选项参数

-l的实现

parser.add_argument('-l') 就增加了选项参数,参数定义为
ls [-h][-l L] [path]

和我们要的形式有一点出入,我们期望的是 [-l] ,怎么解决?

nargs能够解决吗?

parser.add_argument('-l', nargs='?')
ls [-h][-l [L]] [path]

-l还不是可选参数。

那么,直接把nargs=0,意思就是让这个选项接收0个参数,如下

parser.add_argument('-l', nargs=0)

结果,抛出异常

raise ValueError('nargs for store actions must be > 0; if you '
ValueError: nargs for store actions must be > 0; if you have nothing to store, actions such as

store true or store const may be more appropriate

看来nargs是控制位置参数和选项参数的,不能影响选项参数的参数。

为了这个问题,使用action参数

parser.add_argument('-l', action='store_true')

看到命令定义变成了 ls [-h][-l] [path]

提供-l选项,例如

  • ls -l 得到Namespace(l=True, path='.'),提供-l值是True
  • ls 得到Namespace(l=False, path='.'),未提供-l值是False

这样同True、False来判断用户是否提供了该选项

parser.add_argument('-l', action='store_const', const = 20)

# 提供-l选项,属性值为20;否则,对应值为None

-a的实现

 parser.add_argument('-a', '--all', action='store_true') # 长短选项同时给

6.属性名称

参数都是Namespace对象的属性,如果想指定这些属性名,可以使用dest。

parser.add_argument('-l', action='store_true', dest='longfmt')

7.示例

import argparse
 
# 获得一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
# 位置参数,可有可无,缺省值,帮助
parser.add_argument('path', nargs='?', default='.', help='directory')
parser.add_argument('-l', action='store_true', dest='longfmt', help='use along listing format')
parser.add_argument('-a', '--add', action='store_true', help='show all file,do not ignore entrues starting with .')
 
# 分析参数,同时传入可迭代的参数
args = parser.parse_args()
# 打印名称空间中收集的参数
print(args)
# 打印帮助
parser.print_help()
 
# Python学习交流QQ群:153708845 
# 输出
Namespace(path='.', longfmt=False, add=False)
usage: ls [-h] [-l] [-a] [path]
 
list directory contents
 
positional arguments:
  path        directory
 
options:
  -h, --help  show this help message and exit
  -l          use along listing format
  -a, --add   show all file,do not ignore entrues starting with .

8.练习

实现ls命令功能,实现-l、-a和--all、-h选项

实现显示路径下的文件列表

-a和-all 显示包含.开头的文件

-l 详细列表显示

-h 和-l配合,人性化显示文件大小,例如1K、1G、1T等,可以认为1G=1000M

类型字符

  • c 字符

  • d 目录

  • 普通文件

  • l 软链接

  • b 块设备

  • s socket文件

  • p pipe文件,即FIFO

参看Linux、Unix命令ls -lah
-rw-rw-r--   1     python python     5     Oct 25 00:07       test4
mode       硬链接 属主   属组       字节   时间               文件名
按照文件名排序输出,可以和ls的顺序不一样,但要求文件名排序
要求详细列表显示时,时间可以按照“年-月-日 时:分:秒” 格式显示,例如2015-06-17 17:05:00

有关python中argparse模块的用法的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  6. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  9. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐