2011-02-09 17 views
5

¿Por qué no funciona? ¿Qué estoy haciendo mal?Uniendo: cadena y ruta absoluta con os.path

>>> p1 = r'\foo\bar.txt' 
>>> os.path.join('foo1', 'foo2', os.path.normpath(p1)) 
'\\foo\\bar.txt' 

esperaba que esto:

'foo1\\foo2\\foo\\bar.txt' 

Editar:

Una solución

>>> p1 = r'\foo\bar.txt' 
>>> p1 = p1.strip('\\') # Strip '\\' so the path would not be absolute 
>>> os.path.join('foo1', 'foo2', os.path.normpath(p1)) 
'foo1\\foo2\\foo\\bar.txt' 
+0

En mi Python funciona como se esperaba. – rubik

+0

@rubik: ¿Sueles utilizar * nix? – delnan

+0

@ delnan: sí, estoy usando Ubuntu – rubik

Respuesta

8

Cuando os.path.join encuentra una ruta absoluta, descarta lo que se ha acumulado hasta ahora. Una cadena absoluta es aquella que comienza con una barra diagonal (ans en Windows, con una letra de unidad opcional ). normpath no tocará esa barra ya que tiene la misma noción de rutas absolutas. Tienes que quitar esa barra.

Y si puedo preguntar: ¿de dónde viene en primer lugar?

+0

Lo obtuve al dividir una ruta que necesito para agregar a otra ruta. Estoy intentando hacer un código que copia recursivamente archivos/directorios de una carpeta a otra, pero no en "tiempo real", sino creando una lista de diles/dirs, y luego usando la lista para la creación de archivos. – marw

4

p1 es una ruta absoluta (comienza con \) - por lo que se devuelve por sí mismo , según la documentación:

join(a, *p) 
    Join two or more pathname components, inserting "\" as needed. 
    If any component is an absolute path, all previous path components 
    will be discarded. 
+0

Entonces, para obtener el resultado deseado, simplemente cambie la primera línea a 'p1 = r'foo \ bar.txt''. – martineau

+0

Will 'p1.strip ('\\')' en este caso, ¿funciona igual en Linux y Windows? – marw

+1

@marw no será suficiente si tiene otros tipos de rutas absolutas (por ejemplo, comenzando con "/", o comenzando con una letra de unidad como "C:" en Windows). Ver, por ejemplo, el resultado de 'ntpath.join ('foo', 'c: \\ bar')' – ehabkost

2

Si desea que la conducta objetivo de os.path.join para unir dos rutas absolutas juntos, tira hacia fuera del separador:

import os 
p1 = os.path.join(os.sep, 'foo1', 'foo2') 
p2 = os.path.join(os.sep, 'foo', 'bar.txt') 

os.path.join(p1, p2.lstrip(os.sep)) 

Si desea modificar las rutas, también se pueden hacer cosas interesantes como éste usando listas por comprensión :

# Make sure all folder names are lowercase: 
os.path.join(p1, *[x.lower() for x in p2.split(os.sep)]) 
+0

Estoy razonablemente seguro de que 'os.path.join (p1, p2.lstrip (os.sep))' falla en Windows, ya que cada ruta habrá sido prefijada por un especificador de unidad en lugar de 'os.sep'. Dado que las dos rutas pueden residir en diferentes unidades, no está claro qué es lo que hay que hacer en Windows _es_ - lo que probablemente explica por qué 'os.path.join()' se niega silenciosamente a hacer esto, es el primer lugar. –

Cuestiones relacionadas