PythonOS库练习——模拟linux文件管理命令

最近对Python大有兴趣,由于将官网文档看了一遍,但是看完只是简单的了解了Python的语法,而且还只是最基础的语法,所以后续除了了解Python的高级功能外(例外并发机制,锁机制,IO机制等),另一个重要要学习的就是Python的基本类库,如os/sys/datetime等。

本篇文章就是针对Python OS标准库的练习,OS库的功能主要是针对操作系统的文件管理,所以练习无外乎就是针对文件进行操作,如果只是普通的创建个文件/删除个文件/读写下文件/etc,感觉没啥意思,所以就想自己模拟Linux下的文件管理命令来实现一个Python版的,但是在写的过程中发现真的不简单,尤其对于我这样一个初学者来说,不过还是希望能够坚持下去~好了,废话不多说,能写多少写多少吧!

实现框架

首先介绍下整体的框架,框架通过FileManage类进入文件管理器;Context类用于定义上下文,上下文主要用来保存当前工作目录,以后可能还有用户信息等;Command类是一个父类,用于定义通用命令角色;LLCommand类继承自Command类,是一个具体的命令类,LLCommand是用于处理ll命令。目前整体架构还是很简单的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# -*- coding: utf-8 -*-
'''
Created on 2015年11月16日

@author: Vicky
'''

import sys
import os
import datetime

__dir = ""

"""模拟资源管理器"""
class FileManage(object):
'''
classdocs
'''

__tab__ = " "

def __init__(self, _dir):
'''
Constructor
'''

self._dir = _dir
self._context = Context(self._dir)
os.chdir(self._dir)

def _parse(self, inp):
"""解析用户输入"""
_cmd, _params, _vals = ("", [], [])

cmds = inp.split(" ")
_len = len(cmds)
_cmd = cmds[0]
if _len > 1:
for i in range(1, _len):
if cmds[i].startswith("-"):
for s in cmds[i][1:]:
_params.append(s)
else:
_vals.extend(cmds[i:])
break
return (_cmd, _params, _vals)

def __main__(self):
while True:
global __dir
inp = input("fe[%s]:" % self._context._dir)
res = self._parse(inp)
if res[0] == "ll":
LLCommand(self._context, res[0], res[1], res[2]).execute()
elif res[0] == "cd":
print(res)
elif res[0] == "cp":
print(res)
elif res[0] == "exit": # 退出
print("logout...")
sys.exit()
else:
print("-fe: %s: command not found" % res[0])

class Context(object):
"""上下文,保存信息,如当前工作空间"""
def __init__(self, _dir):
self._dir = _dir # 当前用户目录

class Command(object):
"""命令"""
def __init__(self, context, cmd=None, options=None, vals=None):
"""
@param cmd: 命令
@param options: 选项(-a)
@param vals: 参数
@param context: 上下文
"""

if not context:
raise Exception("context is necessary")
self._cmd = cmd
self._options = options
self._vals = vals
self._context = context

def setCmd(self, cmd):
self._cmd = cmd

def setOptions(self, options):
self._options = options

def setVals(self, vals):
self._vals = vals

def execute(self):
pass

def timeToStr(timestamp, _format = "%Y-%m-%d %H:%M:%S"):
"""将时间戳转成字符串"""
_time = datetime.datetime.fromtimestamp(timestamp)
return datetime.date.strftime(_time, _format)

if __name__ == "__main__":
fm = FileManage("E:/Work/Python/files")
fm.__main__()
ll命令实现

直接上代码吧,实现没有什么难度,只是简单的调用os函数而已。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class LLCommand(Command):
"""继承自Command,处理ll命令"""
__tab__ = "\t"
def execute(self):
"""执行命令"""
_dirs = self._vals if self._vals else []
if len(_dirs) == 0:
_dirs.append(self._context._dir)

# 循环列出目录下的文件
for d in _dirs:
self.__none(d)

def __none(self, _dir):
"""递归列出子目录"""
_recursion = False
if "r" in self._options:
_recursion = True
files = []
total = self._list(_dir, files, "", _recursion)
print("total files:%s" % total)
for f in files:
print("{0:7d} {1:19s} {2:s}".format(*f))

def _list(self, _dir, files, _tab="", recursion=False):
old_dir = os.getcwd(); # 保存当前目录
os.chdir(_dir) #进入需要遍历的目录
_total = 0
for f in os.listdir():
_total = _total + 1
stat = os.stat(f)
_size = stat.st_size
_time = timeToStr(int(stat.st_mtime))
files.append((_size, _time, f))
if recursion and os.path.isdir(f):
_total = _total + self._list(f, _tab + self.__tab__, recursion, files)

os.chdir(old_dir) #进入原来的目录
return _total

写下这篇文章主要是鼓励自己学下去,当然如果有人看见了,而且有好的建议,那么就请不宁赐教~