Python-argpase模块

argpase模块

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

$ ls -l /etc/
/etc #位置参数
-l #是选项参数

如何把这些参数传递给程序?

从3.2开始python提供强大的参数分析模块argparse

1.参数分类

  1. 位置参数,参数放在那 需要一个对应的参数位置,比如之前的案例,/etc就是一个参数位置
  2. 选项参数,必须通过前边是-短选项或者- - 长选项,后边加选项参数,选项参数后也可以是没有参数.

在linux中基本命令都是按照如此进行编写例如

ls -alh /etc/openvpn
ls #为命令
-alh #为短选项参数
/etc/openvpn # 位置参数

2.基本解析

来一段基本操作

import argparse

parser = argparse.ArgumentParser() #获得一个参数解析器
agrs  = parser.parse_args()   #分析参数
parser.print_help() #打印帮助

#usage: test1.py [-h]

#optional arguments:
#  -h, --help  show this help message and exit

运行结果

usage: test1.py [-h]

optional arguments:
  -h, --help  show this help message and exit


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

3.解析器的参数

参数名称说明
porg程序名字,缺省使用sys.argv[0]的basename
add_help自动生成解析器增加-h和- - help选项,默认为True
description为程序工程添加描述
import argparse

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list dir or cer') #获得一个参数解析器
agrs  = parser.parse_args()   #分析参数
parser.print_help() #打印帮助

结果

usage: ls [-h]

list dir or cer

optional arguments:
  -h, --help  show this help message and exit

位置参数解析

在linux中ls 是查看文件或者目录使用的,然后将查看内容打印到控制台

打印的时候打印的是位置位置传参

测试代码

import argparse


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list dir or cer ')
parser.add_argument('path')
agrs = parser.parse_args()
parser.print_help()

测试结果

usage: ls [-h] path
ls: error: the following arguments are required: path
#来自googel翻译
用法:ls [-h] 路径
ls:错误:需要以下参数:路径

发现需要提供一个path的参数

1.传参

 parse_agrs(args=None,namespace=None)

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

测试代码

import argparse

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list dir or cer ')
parser.add_argument('path')

args = parser.parse_args(('/etc',)) #将agrs看作参数列表可迭代对象

print (1,args,args.path)
parser.print_help()

运行结果

D:\python_project\venv\Scripts\python.exe D:/python_project/test1.py
1 Namespace(path='/etc') /etc #默认namespace 为args
usage: ls [-h] path

list dir or cer

positional arguments:
  path

optional arguments:
  -h, --help  show this help message and exit

进程已结束,退出代码为 0

那么通过以上实验发现namespace 存储着args的path属性,那么即可通过args.path进行访问

2.非必须位位置参数

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 dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

分析代码

引入 argpase , 定义测试代码ls,加入帮助并开启,描述为list

定义非必须要位置参数,path,nargs表示可有可无,default默认为.也就是当前目录,help表示帮助目录中显示,

定义args的path默认参数为/etc,这是一个迭代器会封装成列表可用agrs.path调用

最后打印

测试结果

D:\python_project\venv\Scripts\python.exe D:/python_project/test1.py
1 Namespace(path='/etc') /etc
usage: ls [-h] [path]###这这这 可选参数!!!!

lisr dir or cer

positional arguments:
  path        path help ##参数描述

optional arguments:
  -h, --help  show this help message and exit

进程已结束,退出代码为 0

可以看出path 也变成可选参数,没有提供默认值,默认的.为缺省值指当前目录

在parser.add_argument中

  1. help代表在帮助文档中参数的描述

  2. nargs 表示这个参数接收结果参数

    ​ ?表示 一个或者没有,可有可无

    ​ +表示至少一个

    ​ *表示可以任意个

    ​ 如果是数字则表示数字代表个数

  3. default 表示如果不提供参数则就是这个值,一般和? *进行配合,因为他都是可以不提供位置参数

选项参数

-l 的实现

测试代码

import argparse
parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',help='list')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()




测试结果

1 Namespace(l=None, path='/etc') /etc
usage: ls [-h] [-l L] [path]

lisr dir or cer

positional arguments:
  path        path help

optional arguments:
  -h, --help  show this help message and exit
  -l L        list

进程已结束,退出代码为 0

通过测试发现 ls [-h] [-l L] [path] 是可以实现的,但是我们只想实现简单的 -l 后边这个大写L并不想要!那直接加nargs可以吗?

测试:

import argparse
parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',nargs=0,help='list')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

测试结果:


Traceback (most recent call last):
  File "D:/python_project/test1.py", line 18, in <module>
    parser.add_argument('-l',nargs=0,help='list')
  File "D:\python\python3.8.10\lib\argparse.py", line 1368, in add_argument
    action = action_class(**kwargs)
  File "D:\python\python3.8.10\lib\argparse.py", line 863, in __init__
    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 
#ValueError:存储操作的 nargs 必须是!= 0; 如果您没有要存储的内容,则诸如 store true 或 store const 之类的操作可能更合适 来自google翻译

经测试发现无法直接nargs =0 他必须是一个非零的,控制选项参数和位置参数,但是python给出了解决方法,store true 和store const,需要测试,store 是action参数选项中的

测试代码:

import argparse
parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',action='store_true',help='list')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

测试结果:

D:\python_project\venv\Scripts\python.exe D:/python_project/test1.py
1 Namespace(l=False, path='/etc') /etc
usage: ls [-h] [-l] [path]

lisr dir or cer

positional arguments:
  path        path help

optional arguments:
  -h, --help  show this help message and exit
  -l          list

进程已结束,退出代码为 0

没有问题 -l就可以看到了.

-a的实现

import argparse
parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',action='store_true')
parser.add_argument('-a','-all',action='store_true',help='look any')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

返回结果:

1 Namespace(a=False, l=False, path='/etc') /etc
usage: ls [-h] [-l] [-a] [path]

lisr dir or cer

positional arguments:
  path        path help

optional arguments:
  -h, --help  show this help message and exit
  -l
  -a, -all    look any

进程已结束,退出代码为 0

属性名称

如果想要自定义namespace 可以使用dest参数进行自定义名称

测试代码:

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='look dir') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l','--list',action='store_true',dest='longfmt',help='use loog list format')
parser.add_argument('-a','-all',action='store_true',help='look any')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

测试结果:

D:\python_project\venv\Scripts\python.exe D:/python_project/test1.py
1 Namespace(a=False, longfmt=False, path='/etc') /etc #在这
usage: ls [-h] [-l] [-a] [path]

lisr dir or cer

positional arguments:
  path        look dir

optional arguments:
  -h, --help  show this help message and exit
  -l, --list  use loog list format
  -a, -all    look any

进程已结束,退出代码为 0

需要实验代码:

需要反复测试,反复练习

import argparse

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list dir or cer') #获得一个参数解析器
agrs  = parser.parse_args()   #分析参数
parser.print_help() #打印帮助


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list dir or cer ')
parser.add_argument('path')

args = parser.parse_args(('/etc',))

print (1,args,args.path)
parser.print_help()

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',nargs=0,help='list')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',action='store_true',help='list')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',action='store_true')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l',action='store_true')
parser.add_argument('-a','-all',action='store_true',help='look any')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()


parser = argparse.ArgumentParser(prog='ls',add_help=True,description='lisr dir or cer')
parser.add_argument('path',nargs='?',default='.',help='look dir') #位置参数,可有可无,缺省值,帮助
parser.add_argument('-l','--list',action='store_true',dest='longfmt',help='use loog list format')
parser.add_argument('-a','-all',action='store_true',help='look any')

args = parser.parse_args(('/etc',))

print (1,args,args.path)

parser.print_help()

作业

实现 ls [-a] [-l] [-h] path 路径

-a 实现查看目录下的文件,包括隐藏文件

-l 查看详细列表

-h 显示文件大小

作业参考:

目前我们上边学习解决了如果自定义参数和传参的问题,但是没有解决业务问题!

需要设计业务

import  argparse
from  pathlib  import Path
from datetime import datetime
import  stat

parser = argparse.ArgumentParser(prog='ls' , add_help=False , description='help dir or cer ')

parser.add_argument('path',nargs='?',help='print path',default='.' )

parser.add_argument('-a','--all',action='store_true',dest='all',help='print all ')

parser.add_argument('-l','--list',action='store_true',dest='long',help='print list' )

parser.add_argument('-h','--human-readable',action='store_true',dest='human',help='--human-readable')

parser.add_argument('-r','--reverse',action='store_true',dest='reverse',help='reverse list')

args = parser.parse_args()
print (args)

parser.print_help()



#业务代码   首先需要想 -l 查看目录文件 联想到path

# def listdir(path,all=False):
#     p =  Path(path)
#     # for f in p.iterdir(): #序列化,将路径下的文件变成一个可迭代对象
#     #     if not all and f.name.startswith('.'):  #判断
#     #         continue
#     #     yield f.name
#     #yield from filter(lambda f:not(not all and f.name.startswith('.')),p.iterdir()) #将以上for进行改造成yield
#     #yield from filter (lambda f : all or not f.name.startswith('.'),p.iterdir()) #
#     yield from  map(lambda x:x.name,filter(lambda f:all or not f.name.startswith('.'),p.iterdir()))
# #分析以上代码 map 传入一个函数和可迭代对象,返回列表,将filter过滤隐藏文件后的本地文件名传入,返回x.name然后通过yield进行返回
# #通过lamdba 进行过滤 p.iterdir 这是将路径进行序列化然后过滤到.开头的文件,返回非.开头的文件


#-a 的实现
def _listdir(path , all,detail,reverse,human):
    """列出详细的文件rwx"""
    p = Path(path)
    for i in  p.iterdir():
        if not  all and i.name.startswith('.'):
            continue #继续的意思
        if not detail :
            yield (i.name,)
        else :
            st = i.stat()
            mode = stat.filemode(st.st_mode)
            mtime = datetime.fromtimestamp(st.st_mtime).strftime('%y %m %d' '%H' '%M' '%S')
            size = st.st_size if not human else _gethuman(st.st_size)
            yield (mode,st.st_nlink,st.st_uid,st.st_gid,size,mtime,i.name)

# -r的实现,查看文件排序
def listdir(path , all=False,detail=False,reverse=False,human=False):
    """列出详细的文件rwx"""
    return sorted(_listdir(path,all,detail,reverse,human),key=lambda x:x[len(x)-1],reverse=reverse)


#-h  的实现

def _gethuman(size= int):
    units = 'KMGTP'
    depth = 0
    while size > 1000 and depth < len(units) -1:
        depth += 1
        size //= 1000
    return  "{}{}".format(size,units[depth] if depth else ' ')


if __name__ == '__main__':
    args = parser.parse_args()
    print (args)
    parser.print_help()
    files = listdir(args.path,args.all,args.long,args.reverse,args.human)
    print (*files,sep='\n')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值