4

を変更pathlib.Path._parse_argsして、他の型 ( など LocalPath) を引数として持つことができるだけでなく、他Pathの型をベース結合のパラメーターとして使用することもできます/..?

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

fromを使用tmplibすると、他のものは自動的に表現に変換されますか?LocalPathpy._path.localstr()

この( pathlib Path および py.test LocalPath)質問に示されているように、サブクラス化とモンキーパッチを試みましたが、うまくいきませんでした。

Path伸びに非常に抵抗があるように見えます。

4

2 に答える 2

1

pathlib(およびPython バージョン < 3.4 の場合) 主に、パス、、および( in )pathlib2に直接関連する 4 つのクラスで構成されます 。これらのそれぞれをサブクラス化し、次の方法でおよびのコードをコピーして適合させる場合:PathPosixPathWindowsPathPurePathBasePathpathlib2Path.__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)

取得するため:

/var/tmp/abc/14/False/testfile.yaml

pathlib2(これを機能させるには、バージョン < 3.4 のパッケージをインストールする必要があります)。

上記はPython 3.6Pathと同じように使用できます。open(p)

適応すると、 ( )やなどのメソッド_parse_argsが自動的にサポートされます。/__truediv__joinpath()relative_to()

于 2016-11-24T20:08:39.377 に答える
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)
于 2016-11-24T20:11:25.657 に答える