使用str子类的os.path.join
有没有人知道为什么 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.path.join
不接受 str
的子类,也不报错(就像用数字或者其他非字符串类型时那样)呢?
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))
这样就可以用了。
如果有疑问,可以查看源代码(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
只会被调用一次,而不是两次。