结合13日和19日更的《python实现windows下的ls函数》和《python类相关装饰器小记》这两篇文章,对ls函数用类封装进行代码重构,主要是熟悉下类的一些基本概念。ls运行结果如下:
主要的改变有以下几点:
- 将argparse解析器以及参数定义函数化为argparse_fun;
- 将判断目录是否合法也函数化为path_legal_or_not;
- 将path_legal_or_not定义为静态方法,和argparse_fun一起封装入ClassArgparse类中;
- LsCommand类中用slot属性插槽(属性插槽是我自己对其的称呼,勿随意效仿哈)将属性列表式存放。
代码直接贴出如下
# -*- encoding=UTF-8 -*-
__author__ = 'wjj1982'
__date__ = '2019/10/13 10:37'
__product__ = 'PyCharm'
__filename__ = 'ls'
import argparse
import os
import time
import prettytable
class ClassArgparse(object):
# def __init__(self):
def argparse_fun(self):
# 定义一个参数解析器
parser = argparse.ArgumentParser(prog='ls', usage='ls.py [-h -a -s -t -r]', add_help=True,description='wjj自写win下的ls命令')
# 获取参数解析器,默认add_help就是True
# 给解析器加入位置参数path和选项参数 a和r
parser.add_argument('path', nargs='?', default='.', help='文件夹路径') # 增加位置参数path
parser.add_argument('-a', '--all', action='store_true', help='列出文件夹下的文件') # 增加选项参数-a
parser.add_argument('-s', '--sorted', action='store_true', help='列出按文件大小排序后的文件夹下的文件') # 增加选项参数-s
parser.add_argument('-t', '--time', action='store_true', help='列出按时间排序后的文件夹下的文件') # 增加选项参数-t
parser.add_argument('-r', '--recursion', action='store_true', help='循环列出文件夹下所有文件') # 增加选项参数-r
# 用解析器解析命令行输入的参数
# args = parser.parse_args() # 分析参数,空表示无参数传入,也可以带参传入,例如:args = parser.parse_args(('-r','-a','.'))
return parser.parse_args()
@staticmethod
def path_legal_or_not(path):
# 判断路径是否合法
directory = path
# 如果指定目录不存在,抛出异常
if not os.path.exists(directory):
raise ValueError(f'{directory} does`t exist') # 等同于 raise ValueError('{} does`t exist'.format(directory))
# 如果directory不是一个目录,抛出异常
if not os.path.isdir(directory):
raise ValueError(f'{directory} is not a directory')
class LsCommand(object):
__slots__ = ('show_all', 'recursion', 'directory', 'show_sorted_size', 'show_sorted_time')
def __init__(self, show_all=False, directory='.', recursion=False, show_sorted_size=False, show_sorted_time=False):
'''
:param show_all: 是否显示隐藏文件
:param directory: 指定的文件目录
:param recursion: 是否递归显示目录下的文件
'''
self.show_all = show_all
self.recursion = recursion
self.directory = os.path.abspath(directory)
self.show_sorted_size = show_sorted_size
self.show_sorted_time = show_sorted_time
def list_dir(self):
'''
处理目录
:param directory: 文件目录
:param grade: 目录层级
:param placeholder: 子目录文件前面的占位符
:return:
'''
# 判断是否为文件夹
# grade是否增加过了
# os.listdir: 列出当前文件夹下面的所有文件和文件夹
# 遍历目录下的文件,文件夹
list_temp2 = []
list_temp3 = []
file_id = 0
if self.show_all:
for i in os.listdir(self.directory):
list_temp1 = []
list_temp1.append(file_id)
list_temp1.append(i)
list_temp1.append(os.path.getsize(self.directory + '\\' + i))
list_temp1.append(
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.stat(self.directory + '\\' + i).st_ctime)))
file_id += 1
if os.path.isdir(self.directory + '\\' + i):
list_temp2.append(list_temp1)
else:
list_temp3.append(list_temp1)
elif not self.show_all:
for i in os.listdir(self.directory):
list_temp1 = []
list_temp1.append(file_id)
list_temp1.append(i)
list_temp1.append('--')
list_temp1.append('--')
file_id += 1
if os.path.isdir(self.directory + '\\' + i):
list_temp2.append(list_temp1)
else:
list_temp3.append(list_temp1)
return list_temp2, list_temp3
# 按照文件大小或者按照时间进行排序,返回排序后的文件列表
def sorted_file(self, list_temp2, list_temp3):
if self.show_sorted_size:
list_temp2 = sorted(list_temp2, key=lambda x: x[2])
list_temp3 = sorted(list_temp3, key=lambda x: x[2])
if self.show_sorted_time:
list_temp2 = sorted(list_temp2, key=lambda x: x[3])
list_temp3 = sorted(list_temp3, key=lambda x: x[3])
return list_temp2, list_temp3
# 定义运行主函数
def run(self):
'''
运行ls命令
:return:
'''
list_temp2, list_temp3 = self.list_dir()
if self.show_sorted_size or self.show_sorted_time:
list_temp2, list_temp3 = self.sorted_file(list_temp2, list_temp3)
return list_temp2, list_temp3
def main():
# args = parser.parse_args()
arg_class = ClassArgparse()
args = arg_class.argparse_fun()
ClassArgparse.path_legal_or_not(args.path)
# arg_class.path_legal_or_not(args.path)
# args = argparse_fun()
# path_legal_or_not(args.path)
ls = LsCommand(args.all, args.path, args.recursion, args.sorted, args.time)
table_x = prettytable.PrettyTable(["ID", "目录名", "目录大小", "创建时间"])
table_x.align['目录名'] = 'l'
table_y = prettytable.PrettyTable(["ID", "文件名", "文件大小", "创建时间"])
table_y.align['文件名'] = 'l'
list_dir_file = ls.run()
for i in list_dir_file[0]:
table_x.add_row(i)
for i in list_dir_file[1]:
table_y.add_row(i)
print(table_x)
print(table_y)
if __name__ == '__main__':
main()