2011-10-07 127 views
5

有誰知道爲什麼os.path.join函數不適用於str的子類?os.path.join與str子類

(我在Windows上使用Python3.2 x64和x86的Python2.7,結果是一樣的)

這是我的代碼有

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' 

但輸出是\\some_file.txt不管值self

我知道我可以做任何str(self)或將其存儲爲self.path和以後使用,但爲什麼os.join.path不接受海峽子,也不產生錯誤(比如當你使用數字或任何非字符串類型)?

回答

0

如有疑問,請查看源代碼(Python32 \ Lib \ ntpath.py)。相關位:

「」「加入兩個或更多個路徑的部件,插入‘\’按需如果任何組分是絕對路徑,所有以前的通路部件將被丟棄。‘’」(強調)

走向函數的底部join試圖使用放置在兩個片之間的\path += '\\' + b(其中bsome_file.txt) - 其中首先添加和\some_file.txt(其是純字符串),然後增加,爲了Path(r'c:\the\path')通過調用Path.__add__(r'c:\the\path', r'\some_file.txt'),將再次致電os.path.join ...

您是否注意到文件名上的前導\?這就是爲什麼路徑的最初部分迷路了。

調用os.path.joinstr(self)(或self.path)的作品,因爲那時os.path.join纔會被調用一次,而不是兩次。

1

看起來好像os.path.join使用__add__方法構建,可以通過在__add__方法中加入print語句來驗證。

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

它的工作原理。

+1

那麼,這就是我剛剛在我的問題中寫的...我想知道它是一個錯誤還是CPython實現或其他。順便說一句'isinstance'將在這種情況下返回True。 – JBernardo

+0

是的,你是對的。它必須有'string .__ class __.__ name__ =='str'' –

+0

不,解釋器不會檢查那個字符串,因爲我可以隨時更改它... – JBernardo