我的具体用例是我正在尝试子类化pathlib.Path.我希望能够添加或覆盖某些功能,但我还想继承所有Path.路径有一个__new__,其中有:
if cls is Path:
cls = WindowsPath if os.name == 'nt' else PosixPath
Run Code Online (Sandbox Code Playgroud)
换句话说,Path需要将适当的类传递给它.问题是我不知道如何既创建我的课,并呼吁Path.__new__有cls == Path.
我尝试了很多东西,每个都给了我一个不同的问题.这个给了我,AttributeError: type object 'RPath' has no attribute '_flavour'因为我试图覆盖父类.
Python3:
class RPath(Path):
def __new__(cls, basedir, *args, **kwargs):
return Path.__new__(cls, *args, **kwargs)
def __init__(self, basedir, *pathsegs):
super().__init__()
self.basedir = basedir
def newfunction(self):
print('Something new')
Run Code Online (Sandbox Code Playgroud)
并且这个返回一个Path对象,因此不允许我做我的覆盖.
def __new__(cls, basedir, *args, **kwargs):
return Path.__new__(Path, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
我也试过各种各样的用法super(),但没有用.
这似乎应该很容易.我错过了什么?
更新:我想要完成什么?具体来说,我想class RPath(basedir, *pathsegments):
rpath=RPath('\root\dir', 'relpath\path2\file.ext)
assert rpath.basedir == '\root\dir' # True
rpath.rebase('\new_basedir')
assert rpath.basedir === '\newbasedir' # True
# And while I'm at it
assert rpath.str == str(rpath) # make str a property == __str__(self)
Run Code Online (Sandbox Code Playgroud)
我认为以通常的方式这是不可能的。但即使你能做到,它也不起作用,因为 Path 所做的也不是返回普通 Path,而是返回一些子类(WindowsPath 或 PosixPath)。因此,您对 Path 的覆盖不会生效,因为如果您能够继承Path.__new__,它仍然会返回 WindowsPath,并且 WindowsPath 继承自 Path,而不是您的自定义路径子类。
它似乎pathlib.Path有一个特殊的类结构,你必须做一些特殊的工作来复制它。初步猜测,您需要创建自己的 WindowsPath 和 PosixPath 子类,然后创建一个 Path 子类来委托实例化其中一个而不是其自身。