23argparse-创新互联

argparse:

成都创新互联公司是一家专注于成都网站设计、做网站、成都外贸网站建设公司与策划设计,王屋网站建设哪家好?成都创新互联公司做网站,专注于网站建设10余年,网设计领域的专业建站公司;建站业务涵盖:王屋等地区。王屋做网站价格咨询:18980820575

习题:

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

显示路径下的文件列表;

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

-l,详细列表显示;

-h和-l,人性化显示文件大小;

c字符,d目录,-普通文件,l软链接,b块设备,s socket文件,p pipe文件即FIFO;

按文件名排序输出,可和ls的顺序不一样;

详细列表显示时,时间按“年-月-日 时:分:秒”格式显示;

-rw-r--r-- 1 root   root    136 May  7 09:45 test.json

mode 硬链接 属主 属组 字节 时间 文件名

参数分类:

ls -l /etc

位置参数,参数放在那里,就要对应一个参数位置,如/etc;

选项参数,必须通过前面是-短选项(短选项后面可以没有参数)或--长选项,然后后面的才算它的参数,如-l;

程序或脚本在运行时,位置参数必须写,argparse默认的-h可有可无;

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

源码:

class ArgumentParser(_AttributeHolder, _ActionsContainer):

"""Object for parsing command line strings into Python objects.

Keyword Arguments:

- prog -- The name of the program (default: sys.argv[0])   #程序的名字,缺省使用sys.argv[0]

- usage -- A usage message (default: auto-generated from arguments)

- description -- A description of what the program does   #为程序功能添加描述

- epilog -- Text following the argument descriptions

- parents -- Parsers whose arguments should be copied into this one

- formatter_class -- HelpFormatter class for printing help messages

- prefix_chars -- Characters that prefix optional arguments

- fromfile_prefix_chars -- Characters that prefix files containing

additional arguments

- argument_default -- The default value for all arguments

- conflict_handler -- String indicating how to handle conflicts

- add_help -- Add a -h/-help option   #自动为解析器增加-h和--help选项,默认为True

"""

def __init__(self,

prog=None,

usage=None,

description=None,

epilog=None,

version=None,

parents=[],

formatter_class=HelpFormatter,

prefix_chars='-',

fromfile_prefix_chars=None,

argument_default=None,

conflict_handler='error',

add_help=True):

def add_argument(self, *args, **kwargs):

"""

add_argument(dest, ..., name=value, ...)

add_argument(option_string, option_string, ..., name=value, ...)

"""

argparse中add_argument()的action参数,内置6种动作可在解析到一个参数时进行触发:

store_true|store_false   #保存相应的布尔值,用于实现布尔开关

store   #默认,保存参数值,可能会先将参数值转换成另一个数据类型,若没显式指定则为默认

store_const   #用于实现非布尔值的命令行标记,保存一个被定义为参数规格的值

append   #将值保存到一个列表中,若参数重复出现,则保存多个值

append_const   #将定义在参数规格中的值保存到一个列表中

version   #打印关于程序的版本信息,然后退出

parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')

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

# parser.add_argument('-l')

# parser.add_argument('-l', nargs='?')

parser.add_argument('-l', action='store_true', help='use a long listing format')

parser.add_argument('-a', '--all', action='store_true', help='show all files,do not ignore entries starting with .')   #长短选项可同时给出

args = parser.parse_args()

print(args)

parser.print_help()

例:

tests.py

import argparse

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

args = parser.parse_args()   #分析参数

parser.print_help()   #打印帮助

>python tests.py -h

usage: tests.py [-h]

optional arguments:

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

例:

import argparse

parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')

parser.add_argument('path')   #path为位置参数,必须提供,否则报error: the following arguments are required

args = parser.parse_args()

print(args)

s>python tests.py

usage: ls [-h] path

ls: error: the following arguments are required: path

例:

import argparse

parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')

parser.add_argument('path')

args = parser.parse_args(('e:/',))   #分析参数,同时传入可迭代的参数,('/etc'.split())或(('/etc'),)或('/etc -all'.split())或(('/etc/','-lah'));Namespace(path='e:/')里的path可通过Namespace对象访问,如args.path

print(args)   #打印名词空间中收集的参数

>python tests.py

Namespace(path='e:/')

例:

import argparse

parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')

parser.add_argument('path', nargs='?', default='.', help='path help')   #default,给path提供默认值,当前路径,path也变成可选的;nargs表示这个参数接收结果参数,?表示可有可无;help表示帮助文档中这个参数的描述

args = parser.parse_args()

print(args)

>python tests.py

Namespace(path='.')

-l和-a的实现:

parser.add_argument('-l')   #效果为

Namespace(l=None, path='.')

usage: ls [-h] [-l L] [path]

parser.add_argument('-l', nargs='?')   #效果为

Namespace(l=None, path='.')

usage: ls [-h] [-l [L]] [path]

parser.add_argument('-l', action='store_true')   #效果为

Namespace(l=False, path='.')

usage: ls [-h] [-l][path]

例:

parser = argparse.ArgumentParser(prog='ls', add_help=False, description='list directory contents')

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

parser.add_argument('-l', action='store_true', help='use a long listing format')

parser.add_argument('-a', '--all', action='store_true', help='show all files,do not ignore entries starting with .')

parser.add_argument('-h', action='store_true', help='making readable easily')

if __name__ == '__main__':

args = parser.parse_args()

print('args=', args)

# parser.print_help()

print(args.path, args.l, args.h, args.all)

>python tests.py -l -a .

args= Namespace(all=True, h=False, l=True, path='.')

. True False True

版本1:

import argparse

from pathlib import Path

import datetime

import win_unicode_console

win_unicode_console.enable()

def _convert_mode(mode: int):

modelst = ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']   #modelst = list('rwx'*3)

modestr = bin(mode)[-9:]

# print(modestr)

ret = ''

for i, c in enumerate(modestr):

if c == '1':

ret += modelst[i]

else:

ret += '-'

return ret

def _convert_human(size: int):

# units =  [' ', 'K', 'M', 'G', 'T', 'P']   # units = list(' KMGTP')

units = ' KMGTP'

depth = 0

while size >= 1000:

size = size // 1000

depth += 1

return '{}{}'.format(size, units[depth])

def _convert_type(file:Path):

ret = ''

if file.is_dir():

ret = 'd'

elif file.is_symlink():

ret = 'l'

elif file.is_socket():

ret = 's'

elif file.is_block_device():

ret = 'b'

elif file.is_char_device():

ret = 'c'

else:

ret = '-'

return ret

def showdir(path: str='.', detail=False, all=False, human=False) -> list:

p = Path(path)

for file in p.iterdir():

# if not all:

#     if file.name.startswith('.'):

#         continue

if not all and file.name.startswith('.'):

continue

if detail:

st = file.stat()

  # print(st)   #os.stat_result(st_mode=33206, st_ino=7599824371282335, st_dev=178462745, st_nlink=1, st_uid=0, st_gid=0, st_size=47, st_atime=1551941978, st_mtime=1551941978, st_ctime=1551928586)

h = str(st.st_size)

if human:

           h = _convert_human(st.st_size)

# drwxr-xr-x 9 ane  ane  4.0K Apr 11 02:40 apache-tomcat-7.0.67

# (33206, 1, 0, 0, 3031, 1557296696.6941395, 'tests.py')

# yield (st.st_mode, st.st_nlink, st.st_uid, st.st_gid, st.st_size, st.st_atime, file.name)

yield (_convert_type(file) + _convert_mode(st.st_mode), st.st_nlink, st.st_uid, st.st_gid, h,

datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S'), file.name)

else:

# print(file.name)

yield file.name

# print(showdir.__annotations__)

parser = argparse.ArgumentParser(prog='ls', add_help=False, description='list directory contents')

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

parser.add_argument('-l', action='store_true', help='use a long listing format')

parser.add_argument('-a', '--all', action='store_true', help='show all files,do not ignore entries starting with .')

parser.add_argument('-h', action='store_true', help='making readable easily')

if __name__ == '__main__':

args = parser.parse_args()

print('args=', args)

# parser.print_help()

print('path={} -l={} -h={} -a={}'.format(args.path, args.l, args.h, args.all))

for file in showdir(args.path, detail=args.l, all=args.all, human=args.h):

print(file)

版本2:

1、使用stat模块,

In [29]: help(stat.filemode)

Help on built-in function filemode in module _stat:

filemode(...)

Convert a file's mode to a string of the form '-rwxrwxrwx'

In [24]: p = Path('gis.log')

In [25]: p.stat

Out[25]:

In [26]: p.stat()

Out[26]: os.stat_result(st_mode=33206, st_ino=1970324837080203, st_dev=178462745, st_nlink=1, st_uid=0, st_gid=0, st_size=70330, st_atime=1550905696, st_mtime=1550905642, st_ctime=1550905696)

In [27]: p.stat().st_mode

Out[27]: 33206

In [28]: stat.filemode(p.stat().st_mode)

Out[28]: '-rw-rw-rw-'

2、整合代码,用到yield from;

import argparse

from pathlib import Path

import datetime

import stat

import win_unicode_console

win_unicode_console.enable()

parser = argparse.ArgumentParser(prog='ls', add_help=False, description='list directory contents')

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

parser.add_argument('-l', action='store_true', help='use a long listing format')

parser.add_argument('-a', '--all', action='store_true', help='show all files,do not ignore entries starting with .')

parser.add_argument('-h', action='store_true', help='making readable easily')

def showdir(path: str='.',  detail=False, all=False, human=False) -> list:

# modelst = ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']  # modelst = list('rwx'*3)

# def _convert_mode(mode: int):

#     modestr = bin(mode)[-9:]

#     # print(modestr)

#     ret = ''

#     for i, c in enumerate(modestr):

#         if c == '1':

#             ret += modelst[i]

#         else:

#             ret += '-'

#     return ret

def _convert_human(size: int):

# units =  [' ', 'K', 'M', 'G', 'T', 'P']   # units = list(' KMGTP')

units = ' KMGTP'

depth = 0

while size >= 1000:

size = size // 1000

depth += 1

return '{}{}'.format(size, units[depth])

# def _convert_type(file:Path):

#     ret = ''

#     if file.is_dir():

#         ret = 'd'

#     elif file.is_symlink():

#         ret = 'l'

#     elif file.is_socket():

#         ret = 's'

#     elif file.is_block_device():

#         ret = 'b'

#     elif file.is_char_device():

#         ret = 'c'

#     else:

#         ret = '-'

#     return ret

def _showdir(path: str='.', detail=False, all=False, human=False) -> list:

p = Path(path)

for file in p.iterdir():

# if not all:

#     if file.name.startswith('.'):

#         continue

if not all and file.name.startswith('.'):

continue

if detail:

st = file.stat()

# print(st)   #os.stat_result(st_mode=33206, st_ino=7599824371282335, st_dev=178462745, st_nlink=1, st_uid=0, st_gid=0, st_size=47, st_atime=1551941978, st_mtime=1551941978, st_ctime=1551928586)

h = str(st.st_size)

if human:

h = _convert_human(st.st_size)

# drwxr-xr-x 9 ane  ane  4.0K Apr 11 02:40 apache-tomcat-7.0.67

# (33206, 1, 0, 0, 3031, 1557296696.6941395, 'tests.py')

# yield (st.st_mode, st.st_nlink, st.st_uid, st.st_gid, st.st_size, st.st_atime, file.name)

# yield (_convert_type(file) + _convert_mode(st.st_mode), st.st_nlink, st.st_uid, st.st_gid, h,

# datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S'), file.name)

yield (stat.filemode(st.st_mode), st.st_nlink, st.st_uid, st.st_gid, h,

datetime.datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S'), file.name)

else:

# print(file.name)

yield file.name

yield from sorted(_showdir(path, detail, all, human), key=lambda x: x[len(x)-1])

# print(showdir.__annotations__)

if __name__ == '__main__':

args = parser.parse_args()

print('args=', args)

# parser.print_help()

print('path={} -l={} -h={} -a={}'.format(args.path, args.l, args.h, args.all))

for file in showdir(args.path, detail=args.l, all=args.all, human=args.h):

print(file)

>python tests.py -lah .

args= Namespace(all=True, h=True, l=True, path='.')

path=. -l=True -h=True -a=True

('-rw-rw-rw-', 1, 0, 0, '47 ', '2019-03-07 14:59:38', '__init__.py')

('drwxrwxrwx', 1, 0, 0, '4K', '2019-04-02 17:15:21', '__pycache__')

('-rw-rw-rw-', 1, 0, 0, '209 ', '2019-03-07 14:42:00', 'admin.py')

('-rw-rw-rw-', 1, 0, 0, '1K', '2019-04-01 13:36:40', 'adminx.py')

('-rw-rw-rw-', 1, 0, 0, '119 ', '2019-03-07 14:59:03', 'apps.py')

('-rw-rw-rw-', 1, 0, 0, '854 ', '2019-03-27 15:12:48', 'forms.py')

('drwxrwxrwx', 1, 0, 0, '4K', '2019-03-07 13:46:16', 'migrations')

('-rw-rw-rw-', 1, 0, 0, '2K', '2019-03-28 16:32:33', 'models.py')

('-rw-rw-rw-', 1, 0, 0, '4K', '2019-05-08 16:05:48', 'tests.py')

('-rw-rw-rw-', 1, 0, 0, '786 ', '2019-03-28 16:10:02', 'urls.py')

('-rw-rw-rw-', 1, 0, 0, '9K', '2019-03-30 15:48:10', 'views.py')

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


新闻名称:23argparse-创新互联
当前网址:http://azwzsj.com/article/dhjcdh.html