pathlib.path允许其他类型的连接除了字符串和路径

时间:2016-11-24 16:39:31

标签: python python-3.x pathlib

如何更改pathlib.Path._parse_args,以便我不仅可以将其他类型(例如LocalPath)作为Path的参数,还可以使用其他类型作为/的参数基于加入等。?

from pathlib import Path
Path(tmplib) / 25 / True

tmplib LocalPath来自py._path.local的{​​{1}},其他人会自动转换为str()个陈述?

我尝试了这个(pathlib Path and py.test LocalPath)问题所示的子类和猴子修补,但是没有用。

Path看起来非常不愿意延长。

2 个答案:

答案 0 :(得分:1)

pathlib(和pathlib2适用于Python版本< 3.4)主要由四个与路径PathPosixPathWindowsPath和{直接相关的类组成{1}}(PurePath中的BasePath)。如果您将每个子类化为子类,并按以下方式复制和调整pathlib2Path.__new__()的代码:

PurePath._parse_args()

您将拥有import os import sys if sys.version_info < (3, 4): import pathlib2 as pathlib else: import pathlib class PurePath(pathlib.Path): __slots__ = () types_to_stringify = [int] @classmethod def _parse_args(cls, args): # This is useful when you don't want to create an instance, just # canonicalize some constructor arguments. parts = [] for a in args: if isinstance(a, pathlib.PurePath): parts += a._parts elif sys.version_info < (3,) and isinstance(a, basestring): # Force-cast str subclasses to str (issue #21127) parts.append(str(a)) elif sys.version_info >= (3, 4) and isinstance(a, str): # Force-cast str subclasses to str (issue #21127) parts.append(str(a)) elif isinstance(a, tuple(PurePath.types_to_stringify)): parts.append(str(a)) else: try: parts.append(a) except: raise TypeError( "argument should be a path or str object, not %r" % type(a)) return cls._flavour.parse_parts(parts) class WindowsPath(PurePath, pathlib.PureWindowsPath): __slots__ = () class PosixPath(PurePath, pathlib.PurePosixPath): __slots__ = () class Path(pathlib.Path): __slots__ = () def __new__(cls, *args, **kwargs): if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath self = cls._from_parts(args, init=False) if not self._flavour.is_supported: raise NotImplementedError("cannot instantiate %r on your system" % (cls.__name__,)) self._init() return self 已经了解Path并且可以用来执行此操作:

int

得到:

from py._path.local import LocalPath

# extend the types to be converted to string on the fly
PurePath.types_to_stringify.extend([LocalPath, bool])

tmpdir = LocalPath('/var/tmp/abc')

p = Path(tmpdir) / 14 / False / 'testfile.yaml'
print(p)

(您需要为版本&lt; 3.4安装软件包/var/tmp/abc/14/False/testfile.yaml 才能使用这些软件包。)

以上pathlib2可以在Python 3.6中用作Path

调整open(p)可让您自动支持_parse_args/)以及__truediv__joinpath()等方法。

答案 1 :(得分:1)

如果你想保持平台独立魔法,你可以做这样的事情:

from py._path.local import LocalPath
import os
import pathlib


class Path(pathlib.Path):

    def __new__(cls, *args, **kwargs):
        if cls is Path:
            cls = WindowsPath if os.name == 'nt' else PosixPath
        return cls._from_parts(map(str, args))

    def __truediv__(self, other):
        return super().__truediv__(str(other))

class WindowsPath(Path, pathlib.WindowsPath):
    pass
class PosixPath(Path, pathlib.PosixPath):
    pass

p = Path(LocalPath())
print(p / 25 / True)

或者如果平台特定的话可以这样做:

from py._path.local import LocalPath
import pathlib


class Path(pathlib.PosixPath):

    def __new__(cls, *args, **kwargs):
        return cls._from_parts(map(str, args))

    def __truediv__(self, other):
        return super().__truediv__(str(other))


p = Path(LocalPath())
print(p / 25 / True)