argparse:
习题:
实现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='.')
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
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)
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]: <bound method Path.stat of WindowsPath('gis.log')>
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')
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。