跳转到主要内容

简单简洁的路径遍历和文件系统访问库。

项目描述

Travis-CI Build Status AppVeyor Build Status Coverage Status PYPI Package PYPI Package

注意: 这处于非常早期的测试版。

简单简洁的路径遍历和文件系统访问库。这个库与其他路径操作库略有不同

  • 路径是字符串的子类。您可以在任何使用字符串的地方使用它们。

  • 几乎所有来自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 (16.7 kB 查看哈希值)

上传时间 源代码

构建分发

pth-0.3.0-py2.py3-none-any.whl (10.3 kB 查看哈希值)

上传时间 Python 2 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面