os.path.join 与 str 子类
Posted
技术标签:
【中文标题】os.path.join 与 str 子类【英文标题】:os.path.join with str subclass 【发布时间】:2011-12-02 16:33:38 【问题描述】:有人知道为什么os.path.join
函数不适用于str
的子类吗?
(我在Windows上使用的是Python3.2 x64和Python2.7 x86,结果是一样的)
这是我的代码
class Path(str):
def __add__(self, other):
return Path(os.path.join(self, other))
p = Path(r'C:\the\path')
d = p + 'some_file.txt'
以及我想要的结果:
'C:\\the\\path\\some_file.txt'
但无论self
的值如何,输出都是\\some_file.txt
。
我知道我可以做 str(self)
或将其存储为 self.path
并稍后使用,但为什么 os.join.path
不接受 str 子类也不引发错误(比如当你使用数字或任何非字符串类型)?
【问题讨论】:
【参考方案1】:如有疑问,请查看源代码 (Python32\Lib\ntpath.py)。相关位:
"""加入两个或多个路径名组件,根据需要插入“\”。如果任何组件是绝对路径,则将丢弃所有以前的路径组件。"""(强调添加)
在函数的底部,join
正在尝试使用 path += '\\' + b
(其中 b
是 some_file.txt
)在两个部分之间放置一个 \
——首先添加 \
和 some_file.txt
(它们是纯字符串),然后通过调用Path.__add__(r'c:\the\path', r'\some_file.txt')
将其添加到Path(r'c:\the\path')
,这将再次调用os.path.join
...
你有没有注意到文件名前面的\
?这就是路径的初始部分丢失的原因。
使用str(self)
(或self.path
)调用os.path.join
是可行的,因为这样os.path.join
只会被调用一次而不是两次。
【讨论】:
【参考方案2】:看起来os.path.join
使用了__add__
方法中的构建,这可以通过在__add__
方法中放置一个打印语句来验证。
>>> class Path(str):
... def __add__(self, other):
... print 'add'
... return Path(os.path.join(str(self), other))
...
>>> p = Path(r'/the/path')
>>> p + 'thefile.txt'
add
>>> class Path(str):
... def __add__(self, other):
... print 'add'
... return Path(os.path.join(self, other))
...
>>> p = Path(r'/the/path')
>>> p + 'file.txt'
add
add
# add printed twice
最简单的解决方案: 改变
return Path(os.path.join(self, other))
到
return Path(os.path.join(str(self), other))
有效。
【讨论】:
嗯,这就是我刚刚在我的问题中写的......我想知道它是一个错误还是 CPython 实现或其他什么。 BTWisinstance
在这种情况下将返回 True
是的,你是对的。它必须有string.__class__.__name__ == 'str'
不,解释器不会检查该字符串,因为我可以随时更改它...
好的,最后一个理论。 os.path.join 使用内置的add。用该信息更新了我的答案
保障措施是os.path.join
使用+=
将路径片段连接在一起——如果将其更改为+
,则会发生无限递归。以上是关于os.path.join 与 str 子类的主要内容,如果未能解决你的问题,请参考以下文章