2009-12-22 18 views

Respuesta

272

Las últimas cadenas no deben comenzar con una barra inclinada. Si comienzan con una barra inclinada, entonces se consideran una "ruta absoluta" y todo lo que se encuentra delante de ellos se descarta.

Citando la Python docs for os.path.join:

Si un componente es una ruta absoluta, todos los componentes anteriores se tiran y unirse continúa desde el componente de ruta absoluta.

Nota sobre Windows, el comportamiento en relación con las letras de unidad, que parece haber cambiado en comparación con versiones anteriores de Python:

En Windows, la letra de unidad no se restablece cuando un componente de la ruta absoluta (por ejemplo, r'\foo'). Si un componente contiene una letra de unidad, todos los componentes anteriores se descartan y la letra de la unidad se restablece. Tenga en cuenta que dado que hay un directorio actual para cada unidad, os.path.join("c:", "foo") representa una ruta relativa al directorio actual en la unidad C: (c:foo), no c:\foo.

+61

-1: ** La cadena "No" debe incluir un "/". Un punto completo de os.path.join es evitar colocar barras en el camino. –

+0

esto no es genial. si explícitamente solicito unirme a esas rutas (o cadenas), hazlo si hay un '/' inicial o no en esa ruta/cadena. – aschmid00

+0

si quieres eso, solo usa str.join(), esto es os.path y por lo tanto es consistente con su semántica de paquete. – marcorossi

4

intento con new_sandbox única

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox') 
11

Es porque su '/new_sandbox/' comienza con / y por lo tanto se supone que es relativo al directorio raíz. Retire el / líder.

3

hacerlo de esta manera, sin demasiado el extra de barras

root="/home" 
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox") 
122

La idea de os.path.join() es hacer que su programa multiplataforma (Linux/Windows/etc).

Incluso una barra lo arruina.

Por lo tanto, solo tiene sentido cuando se utiliza con algún tipo de punto de referencia como os.environ['HOME'] o os.path.dirname(__file__).

53

os.path.join() se puede utilizar junto con os.path.sep para crear una ruta absoluta en lugar de relativa.

os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox') 
+4

¡El uso de 'os.path.sep' como primer elemento para construir una ruta absoluta es mejor que cualquier otra respuesta aquí! El objetivo de usar 'os.path' en lugar de los métodos básicos str es evitar escribir'/'. Poner cada subdirectorio como un nuevo argumento y eliminar todas las barras también es genial. Probablemente sería una buena idea asegurarse con un cheque que 'todaystr' no comience con una barra inclinada. ;) – snooze92

+2

Esto funciona también en Windows (Python 2.7.6). No intervino con 'C: \' y se unió a los subdirectorios. – rickfoosusa

8

Para ayudar a entender por qué este comportamiento sorprendente no es del todo terribles, considere una aplicación que acepta un nombre de archivo de configuración como argumento:

config_root = "/etc/myapp.conf/" 
file_name = os.path.join(config_root, sys.argv[1]) 

Si la aplicación se ejecuta con:

$ myapp foo.conf 

Se usará el archivo de configuración /etc/myapp.conf/foo.conf.

Pero considere lo que sucede si la aplicación se llama con:

$ myapp /some/path/bar.conf 

Entonces myapp debe utilizar el archivo config en /some/path/bar.conf (y no /etc/myapp.conf/some/path/bar.conf o similar).

Puede que no sea genial, pero creo que esta es la motivación para el comportamiento de ruta absoluta.

+0

Gracias! ¡Siempre había odiado este comportamiento hasta leer tu respuesta! Está documentado en https://docs.python.org/3.5/library/os.path.html#os.path.join, pero no la motivación para ello. –

7

Para que su función más portátil, lo utilizan como tales:

os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox') 

o

os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox') 
0

Tenga en cuenta que un problema similar puede morder si se utiliza os.path.join() para incluir una extensión que ya incluye un punto, que es lo que sucede automáticamente cuando usa os.path.splitext(). En este ejemplo:

components = os.path.splitext(filename) 
prefix = components[0] 
extension = components[1] 
return os.path.join("avatars", instance.username, prefix, extension) 

A pesar de que puede haber extension.jpg se termina con una carpeta llamada "foobar" en lugar de un archivo llamado "foobar.jpg". Para evitar esto, debe agregar la extensión por separado:

return os.path.join("avatars", instance.username, prefix) + extension 
Cuestiones relacionadas