2011-10-07 12 views
5

Qualcuno sa perché la funzione os.path.join non funziona con sottoclassi di str?os.path.join con sottoclasse str

(sto usando Python3.2 x64 e x86 Python2.7 su Windows e il risultato è lo stesso)

Questo è il codice che ho

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' 

e il risultato che voglio:

'C:\\the\\path\\some_file.txt' 

ma l'uscita è \\some_file.txt indipendentemente dal valore di self.

so che posso fare sia str(self) o salvarlo come self.path e utilizzare in seguito, ma perché os.join.path non accetta una sottoclasse str né generare un errore (come quando si utilizza un numero o qualsiasi tipo non stringa)?

risposta

0

In caso di dubbi, controllare la fonte (Python32 \ Lib \ ntpath.py). bit rilevanti:

"" "unire due o più componenti nome di un percorso, inserendo '\' al bisogno Se un componente è un percorso assoluto, tutti i componenti di tracciato precedenti vengono scartate.. ''" (corsivo)

verso il fondo della funzione join sta tentando di inserire un \ tra i due pezzi con path += '\\' + b (dove b è some_file.txt) - che per primo aggiunge \ e some_file.txt (che sono stringhe di pianura), poi aggiunge che a Path(r'c:\the\path') chiamando Path.__add__(r'c:\the\path', r'\some_file.txt'), che sarà di nuovo chiamata os.path.join ...

Si è notato il numero iniziale \ sul nome file? Questo è il motivo per cui la parte iniziale del percorso si sta perdendo.

Calling os.path.join con str(self) (o self.path) funziona perché poi os.path.join è solo essere chiamata una volta invece di due volte.

1

Sembra che os.path.join utilizzi il build nel metodo __add__, questo può essere verificato inserendo un'istruzione di stampa nel metodo __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 

soluzione più semplice: Change

return Path(os.path.join(self, other)) 

a

return Path(os.path.join(str(self), other)) 

Funziona.

+1

Beh, questo è quello che ho appena scritto nella mia domanda ... Volevo sapere se si tratta di un bug o implementazione di CPython o qualcos'altro. BTW 'isinstance' restituirà True in questo caso – JBernardo

+0

Sì, hai ragione. Deve avere 'stringa .__ classe __.__ nome__ == 'str'' –

+0

No, l'interprete non controllerebbe quella stringa perché posso cambiarla in qualsiasi momento ... – JBernardo