【发布时间】:2020-09-03 17:11:30
【问题描述】:
我是python的新手。致力于扩展旧模块。到目前为止,它有一个返回 str 的函数(阻塞 shell 命令的输出)。现在我需要该函数也能够返回一个对象,以便以后可以对其进行操作(检查非阻塞 shell 命令的输出)。因此,该函数现在返回我从str 子类化的类的一个实例,以实现向后兼容性。然而,问题是,当这样一个对象被传递给 os.path.isdir - 它总是返回 False,即使字符串是有效路径
import os
class ShellWrap(str):
def __new__(cls, dummy_str_value, process_handle):
return str.__new__(cls,"")
def __init__(self, dummy_str_value, process_handle):
self._ph = process_handle
self._output_str = ""
def wait_for_output(self):
# for simplicity just do
self._output_str = "/Users"
def __str__(self):
return str(self._output_str)
def __repr__(self):
return str(self._output_str)
def __eq__(self,other):
if (isinstance(other, str)):
return other == str(self._output_str)
else:
return super().__eq__(self,other)
>>> obj = ShellWrap("",None)
>>> obj.wait_for_output()
>>> print(type(obj))
... <class '__main__.ShellWrap'>
>>> print (ShellWrap.__mro__)
... <class '__main__.ShellWrap'>
(<class '__main__.ShellWrap'>, <class 'str'>, <class 'object'>)
>>> print(type(obj._output_str))
... <class 'str'>
>>> print(obj)
... /Users
>>> print(obj._output_str)
... /Users
>>> obj == "/Users"
... True
让我困惑的是:
>>> print(os.path.isdir(obj))
... False **<<-- This one puzzles me**
print(os.path.isdir("/Users"))
... True
我尝试添加 PathLike 继承并再实现一个 dunder 但没有成功:
class ShellWrap(str,PathLike):
....
def __fspath__(self):
return self._output_str
似乎还有一个 dunder 我未能实现。但是哪个?
但是,我确实在调试器中看到了一些奇怪的东西。当我将手表放在obj 上时 - 它说它属于str 类,但调试器显示的值没有引号(与其他“纯”strs 不同)。
在调试器中手动为字符串添加引号 - 使其工作,但我猜编辑字符串可能会创建一个新对象,这次是纯 str。
我错过了什么?
编辑:在意识到(请参阅已接受的答案)我尝试做的事情是不可能的之后,我决定挑战必须继承 str 的决定。 所以现在我的班级没有继承任何东西。它只是实现了__str__, __repr__ and __fspath__,这似乎就足够了!显然,只要str 继承存在 - 它获得优先权,dunders 就不会被调用,它会欺骗一些库去获取 str 值的底层 C 存储
【问题讨论】:
-
试试
os.path.isdir(str(obj)),看看是否有效 -
@Luka,谢谢。我知道它有效,但我不能。我不允许在课堂外更改代码。我需要构建我的类,使其完全兼容 str...
-
如果你选择 PathLike,在
__fspath__你可以return str(self._output_str),不是吗? -
自
>>> print(type(obj._output_str)) ... <class 'str'>以来没有任何改变
标签: python string class inheritance subclass