2012-09-26 6 views
12

Sto imparando Python e ho notato qualcosa di strano con uno dei miei script. Facendo un po 'di test ho scoperto il problema derivava da questo comportamento:Perché os.path.join elimina argomenti?

>>> import os 
>>> os.path.join('a','b') 
'a/b' 
>>> os.path.join('a','/b') 
'/b' 

Controllo del documentation, questo è, infatti, la progettazione della funzione:

os.path. unirsi (path1[, path2[, ... ]])

far parte di uno o più componenti del percorso intelligente. Se qualsiasi componente è un percorso assoluto, tutti i componenti precedenti (su Windows, inclusa la precedente lettera di unità, se ce n'è uno) vengono gettati via e l'unione continua. ...

La mia domanda non è why my script failed, ma piuttosto perché la funzione è stato progettato in questo modo. Voglio dire, su Unix almeno, a//b è un modo perfettamente accettabile per designare un percorso, se non elegante. Perché la funzione è stata progettata in questo modo? C'è un modo per dire se uno o più elementi del percorso sono stati scartati prima di testare ogni stringa di percorso con os.path.isabs()?


Per curiosità, ho anche controllato il caso in cui un componente di percorso termina in un carattere os.sep:

>>> os.path.join('a/','b') 
'a/b' 

che funziona come previsto.

+0

Un modo facile, anche se inelegante, per controllare ciò è fare 'filename.lstrip ('/')' – voithos

+3

@voithos Renderlo 'filename.lstrip (os.sep)' ed è portabile alle principali piattaforme. – delnan

+0

@delnan: dovresti testare su windows, dove è 'os.sep + '/'' .. –

risposta

14

Un caso in cui è utile per os.path.join('a', '/b') restituire /b se si chiede a un utente un nome file.

L'utente può inserire un percorso relativo alla directory corrente, o un percorso completo, e il programma in grado di gestire entrambi i casi come questo:

os.path.join(os.getcwd(), filename) 

In [54]: os.getcwd() 
Out[54]: '/tmp' 

In [55]: os.path.join(os.getcwd(), 'foo') 
Out[55]: '/tmp/foo' 

In [56]: os.path.join(os.getcwd(), '/foo/bar') 
Out[56]: '/foo/bar' 
+1

... o qualsiasi altra directory, se esiste una directory predefinita sensibile per l'applicazione. – delnan

+4

E Guido aveva in mente proprio dalla [prima revisione] (http://hg.python.org/cpython/file/5570dbb1ce55/Lib/posixpath.py#11) (dove la funzione è iniziata come 'cat', in seguito essere rinominato in 'join'). –

+0

@Martijn Pieters: È molto interessante. Sarei curioso di sapere se Guido abbia mai spiegato lo scopo del progetto. E grazie unutbu per aver segnalato un caso d'uso significativo. –

1

pensare che stai scrivendo un programma di utilità come cd per verificare la nuova directory, si usa

os.path.join(currdir, newdir) 

se gli Stati Uniti er entra nello /b, tranne per il primo argomento. Questa presa per un sacco di cose usando la directory corrente.