起因
os/os.path/shutil 中的一些接口, 经常让我迷惑, 一会在这个库中, 一会在那个库, 有时候貌似同一个功能有好几个接口, 比如 copy/copyfile/copyfileobj;remove file 的接口貌似在 os 中, remove dir 的接口又在 shutil 中, 经常让人傻傻分不清楚.
再加上年纪越大, 记性能力就呈现出一种可感知的衰减, 越记东西就越记不住, 反复记忆也没用, 不免让人感到哀伤.
使用 Java 貌似就没有这么多纠结, 接口都很符合直觉, 几乎没有记忆过 API, 每次都是 IDE 自动补全 (用到比较少的接口, 根据 IDE 的弹窗也能临时选对, 不用深入源码或文档).
把这些杂七杂八的接口再做一层简单包装, 就是一种很自然的动力, 本文着眼于此, 致力于减少这种心智负担, 尽可能对上提供一致的 API .
包装
这几个标准库的文档很好懂, 并没有什么值得讨论的地方 (可惜就是老记不住 :)), 参照 Java 中对应类的 API, 我们的包装工作也是易如反掌.
如下:
import os
import shutil
class Path:
def __init__(self, pathstr: str):
self._pathstr = pathstr
self._abspath = os.path.abspath(pathstr)
def get_parent(self):
return Path(os.path.dirname(self._abspath))
def get_childs(self):
return [Path(c)
for c in os.listdir(self._abspath)]
def is_absolute(self):
return os.path.isabs(self._pathstr)
def is_dir(self):
return os.path.isdir(self._abspath)
def is_file(self):
return os.path.isfile(self._abspath)
def join(self, s):
return Path(os.path.join(self._abspath, s))
def get_basename(self):
return os.path.basename(self._abspath)
def get_extension(self):
return os.path.splitext(self._abspath)[1]
def get_filename(self):
return os.path.split(self._abspath)[1]
def is_exists(self):
return os.path.exists(self._abspath)
def ends_with(self, ext):
return self._abspath.endswith(ext)
def touch(self):
if self.is_exists():
return True
open(self._abspath, mode='r', encoding='utf-8').close()
return True
def mkdir(self):
if self.is_exists():
return
os.makedirs(self._abspath)
return True
def rm(self):
if not self.is_exists():
return
if self.is_file():
os.remove(self._abspath)
if self.is_dir():
shutil.rmtree(self._abspath)
def mv(self, dest):
shutil.move(self._abspath, dest)
def cp(self, dest):
if self.is_file():
shutil.copyfile(self._abspath, dest)
if self.is_dir():
shutil.copytree(self._abspath, dest)
class File:
def __init__(self, filestr: str):
if not os.path.isfile(filestr):
raise ValueError('must be a real file, now is %s' % filestr)
self._filestr = os.path.abspath(filestr)
self._statresult = os.stat(self._filestr)
def get_size(self):
return self._statresult.st_size
def get_create_time(self):
return self._statresult.st_ctime
使用如下:
Path('/root/newfile').touch()
Path('/root/newdir').mkdir()
不妨将其放到项目的 utils/ 下面, 这样就再也不用记忆那一堆乱糟糟的 API 了.:)
好处
其实, Python 标准库的很多 API, 直接使用时, 总是需要临时查查文档, 或是反复记忆, 使用频率很高也都要查阅文档 (感觉是 API 设计不佳), 不免让人小烦恼. 这个时候, 做一层简单的包装或转发, 可以立刻减少这种痛苦
来源: https://juejin.im/post/5a71ba106fb9a01ca915c31c