Skip to main content

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

项目描述

Travis-CI 构建状态 AppVeyor 构建状态 覆盖状态 PYPI 包 PYPI 包

注意:这是处于非常 alpha 状态。

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

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

  • 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()。接受任何打开的参数(当然文件名除外)。

  • 对 .zip 文件中的文件的透明支持。

基本上,它是为极其简洁而设计的。它共享Unipath的 str-subclassing 方法,并且具有无缝 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'

自动包装拉链:

>>> 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'

邮编:

>>> 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'>

待办事项:让它变得更好。

>>> 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 查看哈希)

已上传 source

内置分布

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

已上传 2 7