Por ejemplo, quiero unir una ruta de prefijo a rutas de recursos como /js/foo.js.
Quiero que la ruta resultante sea relativa a la raíz del servidor. En el ejemplo anterior, si el prefijo era "media", me gustaría que el resultado fuera /media/js/foo.js.
os.path.join hace esto muy bien, pero la forma en que une las rutas depende del sistema operativo. En este caso, sé que estoy apuntando a la web, no al sistema de archivos local.
¿Existe una mejor alternativa cuando trabaja con rutas que sabe que se utilizarán en las URL? ¿Os.path.join funcionará lo suficientemente bien? ¿Debería enrollar el mío?

os.path.joinno trabajará. Pero simplemente unirse por el/carácter debería funcionar en todos los casos:/es el separador de ruta estándar en HTTP según la especificación.Respuestas:
Dado que, a partir de los comentarios que publicó el OP, parece que no quiere conservar "URL absolutas" en la unión (que es uno de los trabajos clave de
urlparse.urljoin;-), recomiendo evitarlo.os.path.jointambién sería malo, exactamente por la misma razón.Entonces, usaría algo como
'/'.join(s.strip('/') for s in pieces)(si el encabezado/también debe ignorarse, si el encabezado debe tener una carcasa especial, eso también es factible, por supuesto ;-).fuente
os.path.join('http://media.com', 'content')volveráhttp://media.com\content.Puede utilizar
urllib.parse.urljoin:Pero cuidado :
La razón por la que obtienes resultados diferentes de
/js/foo.jsyjs/foo.jses porque el primero comienza con una barra que significa que ya comienza en la raíz del sitio web.En Python 2, tienes que hacer
fuente
urljoinalguna vez elimine '/'. Si lo llamo conurlparse.urljoin('/media/', '/js/foo.js')el valor devuelto es '/js/foo.js'. Eliminó todos los medios, no el duplicado '/'. De hecho, enurlparse.urljoin('/media//', 'js/foo.js')realidad devuelve '/media//js/foo.js', por lo que no se eliminan los duplicados.urljoinno es para unirse a URL. Es para resolver URL relativas como se encuentran en documentos HTML, etc.Como dices,
os.path.joinune rutas basadas en el sistema operativo actual.posixpathes el módulo subyacente que se utiliza en los sistemas posix bajo el espacio de nombresos.path:Por lo tanto, puede importar y usar
posixpath.joinen su lugar las URL, que están disponibles y funcionarán en cualquier plataforma .Editar: la sugerencia de @ Pete es buena, puede alias de la importación para una mayor legibilidad
Editar: Creo que esto queda más claro, o al menos me ayudó a entender, si miras la fuente de
os.py(el código aquí es de Python 2.7.11, además he recortado algunos bits). Hay importaciones condicionalesos.pyque eligen qué módulo de ruta usar en el espacio de nombresos.path. Todos los módulos subyacentes (posixpath,ntpath,os2emxpath,riscospath) que pueden ser importados enos.py, alias comopath, hay y existen para ser utilizado en todos los sistemas.os.pyes simplemente elegir uno de los módulos para usar en el espacioos.pathde nombres en tiempo de ejecución según el sistema operativo actual.fuente
from posixpath import join as urljoinmuy bien lo alias a algo fácil de leer.Esto hace bien el trabajo:
fuente
La función basejoin en el paquete urllib podría ser lo que está buscando.
Editar: no me di cuenta antes, pero urllib.basejoin parece mapear directamente a urlparse.urljoin, lo que hace que este último sea el preferido.
fuente
Usando furl,
pip install furlserá:fuente
.urlal final:furl.furl('/media/path/').add(path='js/foo.js').urlfurl('/media/path/').add(path=furl('/js/foo.js').path).urlporquefurl('/media/path/').add(path='/js/foo.js').urles/media/path//js/foo.jsSé que esto es un poco más de lo que pidió el OP, sin embargo, tenía las piezas para la siguiente URL y estaba buscando una forma sencilla de unirme a ellas:
Mirando alrededor:
Entonces, además de la ruta de unión que ya se ha respondido en las otras respuestas, para obtener lo que estaba buscando, hice lo siguiente:
Según la documentación, se necesita EXACTAMENTE una tupla de 5 partes.
Con el siguiente formato de tupla:
fuente
Rune Kaagaard proporcionó una solución excelente y compacta que funcionó para mí, la amplié un poco:
Esto permite que todos los argumentos se unan independientemente de las barras al final y al final mientras se conserva la última barra si está presente.
fuente
return "/".join([str(x).strip("/") for x in args]) + trailing_slashPara mejorar ligeramente la respuesta de Alex Martelli, lo siguiente no solo limpiará las barras adicionales, sino que también conservará las barras finales (finales), que a veces pueden ser útiles:
Sin embargo, no es tan fácil de leer y no limpiará varias barras finales adicionales.
fuente
Encontré cosas que no me gustaron de todas las soluciones anteriores, así que se me ocurrió la mía. Esta versión asegura que las partes se unan con una sola barra y deja las barras al principio y al final solas. No
pip install, sinurllib.parse.urljoinrarezas.fuente
Usando furl y regex (python 3)
fuente