2013-04-03 9 views
8

Sto scrivendo uno script per analizzare più file di registro e mantenere un elenco dei file che sono stati elaborati. Quando ho letto la lista dei file da elaborare Io uso os.walk e ottenere nomi simili al seguente:Python - Can (o should) I change os.path.sep?

C:/Users/Python/Documents/Logs\ServerUI04\SystemOut_13.01.01_20.22.25.log 

Questo viene creato il seguente codice:

filesToProcess.extend(os.path.join(root, filename) for filename in filenames if logFilePatternMatch.match(filename)) 

Sembra che "root" utilizzato in avanti barra come separatore (sono su Windows e lo trovo più comodo), ma "nomefile" usa i backslash e quindi finisco con un percorso incoerente per il file poiché contiene una combinazione di barre avanti e indietro come separatori.

Ho provato a fissare il separatore con:

os.path.sep = "/" 

e

os.sep = "/" 

Prima .join ma sembra non avere effetto. Mi rendo conto che in teoria potrei manipolare la stringa ma a lungo termine vorrei che il mio script potesse girare su Unix e Windows, quindi preferirei che fosse dinamico se possibile.

Mi manca qualcosa?

Aggiornamento:

In base alle risposte utili di seguito sembra che il mio problema era auto inflitta, per comodità avevo impostare il percorso iniziale utilizzato come root in questo modo:

logFileFolder = ['C:/Users/Python/Documents/Logs'] 

Quando ho cambiato a questo:

logFileFolder = ['C:\\Users\\Python\\Documents\\Logs'] 

tutto funziona ed i miei percorsi dei file risultanti tutti utilizzare il "\" in tutto. Sembra che il mio approccio fosse sbagliato in quanto stavo cercando di far sì che Python cambiasse comportamento piuttosto che correggere quello che stavo impostando come valore.

Grazie!

+2

andrò su un arto e dire che l'impostazione 'os.sep' non è probabilmente il diritto soluzione. –

+0

possibile duplicato di [Perché non os.path.join utilizzare os.path.sep o os.sep?] (Http://stackoverflow.com/questions/12086224/why-not-os-path-join-use-os -path-sep-or-os-sep) – BrenBarn

+0

Come anser per quella domanda duplicata, 'os.path' funziona importando' posixpath' o 'ntpath' a seconda del sistema operativo. È interessante notare che nel codice sorgente di questi moduli è possibile vedere che il separatore di percorso è hard-coded come stringa letterale all'interno della funzione 'join', quindi non sarà possibile cambiarlo senza scrivere la propria funzione' join'. – BrenBarn

risposta

7

vorrei tenere le dita fuori os.sep e utilizzare os.path.normpath() sul risultato della combinazione della radice e il nome del file:

filesToProcess.extend(os.path.normpath(os.path.join(root, filename)) 
      for filename in filenames if logFilePatternMatch.match(filename))  
1

Sei meglio non toccare os.sep e os.path.sep come non sono ciò che sta usando os.path.join. Potresti usare os.path.normpath come suggerito da Anthon. Un'altra alternativa è quella di avere il proprio percorso semplice registrazione:

os.sep.join([i1,i2,i3])

4

Io uso '/'.join([path1, path2]) per risolvere questo problema soltanto, perche '/' funziona bene in Windows e Linux.

+1

Non funzionerà comunque in tutti i casi. Ad esempio, 'explorer.exe' accetta solo argomenti di percorso specificati con' \ '. – minerz029

0

Ho preferito la seguente funzione di utilità.

from os.path import sep, join 

def pjoin(*args, **kwargs): 
    return join(*args, **kwargs).replace(sep, '/') 

Converte entrambe le varianti (stile linux e stile windows) in stile linux. Sia windows che linux supportano il separatore '/' in python.

Ho respinto il semplicistico os.sep.join (['str', 'str', 'str']) perché non tiene conto dei separatori esistenti. Prendete il caso seguente con sep.join vs vaniglia si uniscono:

In[79]: os.sep.join(['/existing/my/', 'short', 'path']) 
Out[79]: '/existing/my/\\short\\path' 
In[80]: os.path.join('/existing/my/', 'short', 'path') 
Out[80]: '/existing/my/short\\path' 

La vaniglia join potrebbe essere riparato con il suggerito:

In[75]: os.path.normpath(os.path.join('/existing/my/', 'short', 'path')) 
Out[75]: '\\existing\\my\\short\\path' 

Fin qui tutto dio. Ma poi introduciamo il seguente scenario in cui interagiremo con Linux da Windows.

local_path = os.path.normpath(os.path.join('C:\\local\\base', 'subdir', 'filename.txt')) 
remote_path = os.path.normpath(os.path.join('/remote/base', 'subdir', 'filename.txt')) 
sftp_server.upload(local_path, remote_path) 

Quanto sopra, allora non riuscire perché il server SFTP si aspetta un separatore '/' mentre os.path.normpath sarà sulle finestre normalizzare a '\'.

Utilizzando la funzione di utilità pjoin o simile, funzionerà OS croce, web, ftp, ecc