2016-11-24 43 views
1

加盟除了如何变更pathlib.Path._parse_args,这样我不仅可以有其他类型(如LocalPath)作为参数传递给Path也使用基于加入其他类型作为参数/,等等..?pathlib.path允许其他类型的字符串和路径

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

随着tmplibpy._path.local一个LocalPath,其他自动转换为自己的str()交涉?

我试过子分类和猴子修补,如(pathlib Path and py.test LocalPath)问题所示,但没有奏效。

Path看起来很难延伸。

回答

1

pathlib(和pathlib2为Python版本< 3.4)主要由直接相关的路径PathPosixPath,(在pathlib2BasePathWindowsPathPurePath四类。如果你继承每一种复制并适应以下列方式为Path.__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为此在这些工作)。

以上Path可以在Python 3.6中用作open(p)

适应_parse_args给你喜欢的joinpath()/__truediv__)自动支持以及方法,relative_to()

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) 
+1

虽然它看起来比我的解决方案更简单,但它不会抱怨任何可以表示为字符串的**类型。如果你想使用'joinpath()','realtive_to()'等,你还必须引入每一个定义。 – Anthon

相关问题