简单简洁的路径遍历和文件系统访问库。
项目描述
注意: 这处于非常早期的测试版。
简单简洁的路径遍历和文件系统访问库。这个库与其他路径操作库略有不同
路径是字符串的子类。您可以在任何使用字符串的地方使用它们。
几乎所有来自os.path的内容都可以作为同名的属性使用,除了
os.path.relpath是一个方法
os.path.getsize变成了名为size的属性
os.path.getatime变成了名为atime的属性
os.path.getctime变成了名为ctime的属性
os.path.getmtime变成了名为mtime的属性
os.path.split变成了名为splitpath的方法,因为split已经是字符串方法了
os.path.join变成了名为joinpath的方法,因为join已经是字符串方法了
os.path.commonprefix 未实现
os.path.basename 变成名为 name 的 属性
os.path.dirname 变成名为 dir 的 属性
os.listdir 变成名为 list 的 属性
os.walk 变成名为 tree 的 属性
调用 Path 对象会调用路径上的 open()。接受 open 可以接受的任何参数(当然不包括文件名)。
透明支持 .zip 文件中的文件。
基本上,它是为了极致的简洁而设计的。它采用了 Unipath 的 str 子类化方法,并且具有无缝的 zip 支持(类似于 Twisted 的 ZipPath)。
用法
入门指南
>>> import pth >>> pth # the module is a function! <function pth at ...> >>> p = pth("a.txt") >>> p <Path 'a.txt'> >>> p <Path 'a.txt'>
API
>>> p = pth('tests') >>> p <Path 'tests'>
连接路径
>>> p/"a"/"b"/"c"/"d" <Path 'tests/a/b/c/d'> >>> p/"/root" <Path '/root'>
属性
>>> p.abspath <Path '/.../tests'> >>> p2 = p/'b.txt' >>> p2 <Path 'tests/b.txt'> >>> p.exists True >>> p2.isfile True >>> p2() <...'tests/b.txt'...mode...'r'...> >>> pth('bogus-doesnt-exist')() Traceback (most recent call last): ... pth.PathMustBeFile: [Errno 2] No such file or directory: ...
遍历子项,包括 .zip 文件中的文件
>>> for i in sorted([i for i in p.tree]): print(i) tests/a tests/a/a.txt tests/b.txt tests/test.zip tests/test.zip/1 tests/test.zip/1/1.txt tests/test.zip/B.TXT tests/test.zip/a.txt >>> for i in sorted([i for i in p.files]): print(i) tests/b.txt >>> for i in sorted([i for i in p.dirs]): print(i) tests/a tests/test.zip >>> for i in sorted([i for i in p.list]): print(i) tests/a tests/b.txt tests/test.zip >>> list(pth('bogus-doesnt-exist').tree) Traceback (most recent call last): ... pth.PathMustBeDirectory: <Path 'bogus-doesnt-exist'> is not a directory nor a zip !
尝试访问不存在的属性
>>> p.bogus Traceback (most recent call last): ... AttributeError: 'Path' object has no attribute 'bogus'
自动包装 zip 文件
>>> p/'test.zip' <ZipPath 'tests/test.zip' / ''>
其他属性
>>> p.abspath <Path '/.../tests'> >>> p.abs <Path '/.../tests'> >>> p.basename <Path 'tests'> >>> p.abs.basename <Path 'tests'> >>> p.name <Path 'tests'> >>> p.dirname <Path ''> >>> p.dir <Path ''> >>> p.exists True >>> pth('~root').expanduser <Path '/root'> >>> pth('~/stuff').expanduser <Path '/home/.../stuff'> >>> p.expandvars <Path 'tests'> >>> type(p.atime) <... 'float'> >>> type(p.ctime) <... 'float'> >>> type(p.size) <... 'int'> >>> p.isabs False >>> p.abs.isabs True >>> p.isdir True >>> p.isfile False >>> p.islink False >>> p.ismount False >>> p.lexists True >>> p.normcase <Path 'tests'> >>> p.normpath <Path 'tests'> >>> p.realpath <Path '/.../tests'> >>> p.splitpath (<Path ''>, <Path 'tests'>) >>> pth('a/b/c/d').splitpath (<Path 'a/b/c'>, <Path 'd'>) >>> pth('a/b/c/d').parts [<Path 'a'>, <Path 'b'>, <Path 'c'>, <Path 'd'>] >>> pth('/a/b/c/d').parts [<Path '/'>, <Path 'a'>, <Path 'b'>, <Path 'c'>, <Path 'd'>] >>> pth(*pth('/a/b/c/d').parts) <Path '/a/b/c/d'> >>> p.splitdrive ('', <Path 'tests'>) >>> p.drive '' >>> [i for i in (p/'xxx').tree] Traceback (most recent call last): ... pth.PathMustBeDirectory: <Path 'tests/xxx'> is not a directory nor a zip ! >>> (p/'xxx').isfile False >>> (p/'xxx')() Traceback (most recent call last): ... pth.PathMustBeFile: ... 2... >>> p() Traceback (most recent call last): ... pth.PathMustBeFile: <Path 'tests'> is not a file ! >>> pth('a.txt').splitext (<Path 'a'>, '.txt') >>> pth('a.txt').ext '.txt'
Zip 相关内容
>>> z = pth('tests/test.zip') >>> z <ZipPath 'tests/test.zip' / ''> >>> z.abspath <ZipPath '/.../tests/test.zip' / ''> >>> z.abs <ZipPath '/.../tests/test.zip' / ''> >>> z.basename # transforms in normal path cauze zip is not accessible in current dir <Path 'test.zip'> >>> z.abs.basename # transforms in normal path cauze zip is not accessible in current dir <Path 'test.zip'> >>> import os >>> os.chdir('tests') >>> z.basename <ZipPath 'test.zip' / ''> >>> z.name <ZipPath 'test.zip' / ''> >>> os.chdir('..') >>> z.dirname <Path 'tests'> >>> z.abs.dirname <Path '/.../tests'> >>> z.dir <Path 'tests'> >>> z.exists True >>> pth('~root').expanduser <Path '/root'> >>> pth('~/stuff').expanduser <Path '/home/.../stuff'> >>> z.expandvars <ZipPath 'tests/test.zip' / ''> >>> type(z.atime) Traceback (most recent call last): ... AttributeError: Not available here. >>> type(z.ctime) <... 'float'> >>> type(z.size) <... 'int'> >>> z.isabs False >>> z.abs.isabs True >>> z.isdir True >>> z.isfile False >>> z.islink False >>> z.ismount False >>> z.lexists Traceback (most recent call last): ... AttributeError: Not available here. >>> for i in z.tree: print((str(i), repr(i))) ('tests/test.zip/1',...... "<ZipPath 'tests/test.zip' / '1/'>") ('tests/test.zip/1/1.txt', "<ZipPath 'tests/test.zip' / '1/1.txt'>") ('tests/test.zip/B.TXT',..."<ZipPath 'tests/test.zip' / 'B.TXT'>") ('tests/test.zip/a.txt',..."<ZipPath 'tests/test.zip' / 'a.txt'>") >>> for i in z.files: print((str(i), repr(i))) ('tests/test.zip/B.TXT',..."<ZipPath 'tests/test.zip' / 'B.TXT'>") ('tests/test.zip/a.txt',..."<ZipPath 'tests/test.zip' / 'a.txt'>") >>> for i in z.dirs: print((str(i), repr(i))) ('tests/test.zip/1',...... "<ZipPath 'tests/test.zip' / '1/'>") >>> for i in z.list: print((str(i), repr(i))) ('tests/test.zip/1',...... "<ZipPath 'tests/test.zip' / '1/'>") ('tests/test.zip/B.TXT',..."<ZipPath 'tests/test.zip' / 'B.TXT'>") ('tests/test.zip/a.txt',..."<ZipPath 'tests/test.zip' / 'a.txt'>") >>> (z/'B.TXT') <ZipPath 'tests/test.zip' / 'B.TXT'> >>> str(z/'B.TXT') 'tests/test.zip/B.TXT' >>> (z/'B.TXT').dirname <ZipPath 'tests/test.zip' / ''> >>> (z/'B.TXT').rel(z) <Path 'B.TXT'> >>> z.rel(z/'B.TXT') <Path '..'> >>> (z/'B.TXT').exists True >>> (z/'B.TXT').normcase <ZipPath 'tests/test.zip' / 'B.TXT'> >>> (z/'B.TXT').normpath <ZipPath 'tests/test.zip' / 'B.TXT'> >>> (z/'B.TXT').name <Path 'B.TXT'> >>> (z/'B.TXT').name <Path 'B.TXT'> >>> z.normcase <ZipPath 'tests/test.zip' / ''> >>> z.normpath <ZipPath 'tests/test.zip' / ''> >>> z.realpath <ZipPath '/.../tests/test.zip' / ''> >>> z.splitpath (<Path 'tests'>, <Path 'test.zip'>) >>> z.splitdrive ('', <ZipPath 'tests/test.zip' / ''>) >>> z.drive '' >>> pth('a.txt').splitext (<Path 'a'>, '.txt') >>> pth('a.txt').ext '.txt'
在 .zip 文件中处理文件
>>> p = z/'B.TXT' >>> p.abspath <ZipPath '/.../tests/test.zip' / 'B.TXT'> >>> p.abs <ZipPath '/.../tests/test.zip' / 'B.TXT'> >>> p.basename <Path 'B.TXT'> >>> p.abs.basename <Path 'B.TXT'> >>> p.name <Path 'B.TXT'> >>> p.dirname <ZipPath 'tests/test.zip' / ''> >>> p.dir <ZipPath 'tests/test.zip' / ''> >>> p.exists True >>> type(p.atime) Traceback (most recent call last): ... AttributeError: Not available here. >>> type(p.ctime) <... 'float'> >>> type(p.size) <... 'int'> >>> p.isabs False >>> p.abs.isabs True >>> p.isdir False >>> p.isfile True >>> p.islink False >>> p.ismount False >>> p.lexists Traceback (most recent call last): ... AttributeError: Not available here. >>> p.normcase <ZipPath 'tests/test.zip' / 'B.TXT'> >>> p.normpath <ZipPath 'tests/test.zip' / 'B.TXT'> >>> p.realpath <ZipPath '/.../tests/test.zip' / 'B.TXT'> >>> p.splitpath (<ZipPath 'tests/test.zip' / ''>, <Path 'B.TXT'>) >>> pth.ZipPath.from_string('tests/test.zip/1/1.txt') <ZipPath 'tests/test.zip' / '1/1.txt'> >>> p.splitdrive ('', <ZipPath 'tests/test.zip' / 'B.TXT'>) >>> p.drive '' >>> p.splitext (<ZipPath 'tests/test.zip' / 'B'>, '.TXT') >>> p.ext '.TXT' >>> p.joinpath('tete') <ZipPath 'tests/test.zip' / 'B.TXT/tete'> >>> p.joinpath('tete').exists False >>> p.joinpath('tete').isdir False >>> p.joinpath('tete').isfile False >>> p.joinpath('tete').ctime Traceback (most recent call last): ... pth.PathDoesNotExist: "There is no item named 'B.TXT/tete' in the archive" >>> p.joinpath('tete').size Traceback (most recent call last): ... pth.PathDoesNotExist: "There is no item named 'B.TXT/tete' in the archive" >>> p.relpath('tests') <Path 'test.zip/B.TXT'> >>> p.joinpath('tete')('rb') Traceback (most recent call last): ... pth.PathMustBeFile: <ZipPath 'tests/test.zip' / 'B.TXT/tete'> is not a file ! >>> p('r') <zipfile.ZipExtFile ...> >>> [i for i in p.tree] Traceback (most recent call last): ... pth.PathMustBeDirectory: <ZipPath 'tests/test.zip' / 'B.TXT'> is not a directory ! >>> z('rb') Traceback (most recent call last): ... pth.PathMustBeFile: <ZipPath 'tests/test.zip' / ''> is not a file !
遍历 zip 文件的内容
>>> [i for i in z.tree] [<ZipPath 'tests/test.zip' / '1/'>, <ZipPath 'tests/test.zip' / '1/1.txt'>, <ZipPath 'tests/test.zip' / 'B.TXT'>, <ZipPath 'tests/test.zip' / 'a.txt'>] >>> [i for i in z.files] [<ZipPath 'tests/test.zip' / 'B.TXT'>, <ZipPath 'tests/test.zip' / 'a.txt'>] >>> [i for i in z.dirs] [<ZipPath 'tests/test.zip' / '1/'>]
注意,在连接绝对路径时存在这种不一致性
>>> z/pth('/root') <Path '/root'>
与
>>> z/'/root' <ZipPath 'tests/test.zip' / '/root'>
TODO:使其更美观。
>>> pth.ZipPath('tests', '', '') <Path 'tests'> >>> pth.ZipPath.from_string('/bogus/path/to/stuff/bla/bla/bla') <Path '/bogus/path/to/stuff/bla/bla/bla'> >>> pth.ZipPath.from_string('bogus') <Path 'bogus'> >>> pth.ZipPath.from_string('tests/test.zip/bogus/path/to/stuff/bla/bla/bla') <ZipPath 'tests/test.zip' / 'bogus/path/to/stuff/bla/bla/bla'> >>> pth.ZipPath.from_string('tests/1/bogus/path/to/stuff/bla/bla/bla') <Path 'tests/1/bogus/path/to/stuff/bla/bla/bla'> >>> pth.ZipPath.from_string('tests') <Path 'tests'> >>> pth.ZipPath.from_string('tests/bogus') <Path 'tests/bogus'>
还有一个 临时路径
>>> t = pth.TempPath() >>> t <TempPath '/tmp/...'> >>> with t: ... with (t/"booo.txt")('w+') as f: ... _ = f.write("test") ... print([i for i in t.tree]) [<Path '/tmp/.../booo.txt'>] >>> t.exists False
变更日志
0.1.0 (2014-06-10)
首次发布在 PyPI 上。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。
源代码分发
构建分发
pth-0.3.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 206e5f104d8f4949b66c6f418d30e585546ef8cdd08428a556ddc43f25c07cd4 |
|
MD5 | 02e3cfe0e74f06292cf9729c4de30f78 |
|
BLAKE2b-256 | 6f6831fda6cb2092373ce5ba460139b0ee37814411927e3a6f5e9847679b6ef7 |
pth-0.3.0-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1c7f7b1456ec8a97ac2ea71b1f1ceb7d35fcdcd07c8845fda5585b8fb157aa97 |
|
MD5 | 9c00d19f1ae7fa2c5c352b08b81d11b2 |
|
BLAKE2b-256 | 880a0c01ca43eace546a12bc2fd2ab95588c1a87c3fec853d169ff57c1a60168 |