Par exemple, je veux joindre un chemin de préfixe aux chemins de ressources comme /js/foo.js.
Je veux que le chemin résultant soit relatif à la racine du serveur. Dans l'exemple ci-dessus, si le préfixe était "media", je voudrais que le résultat soit /media/js/foo.js.
os.path.join le fait très bien, mais la façon dont il joint les chemins dépend du système d'exploitation. Dans ce cas, je sais que je cible le Web, pas le système de fichiers local.
Existe-t-il une meilleure alternative lorsque vous travaillez avec des chemins dont vous savez qu'ils seront utilisés dans les URL? Os.path.join fonctionnera-t-il assez bien? Dois-je simplement rouler le mien?
os.path.join
ne fonctionnera pas. Mais la simple jonction par le/
caractère devrait fonctionner dans tous les cas -/
est le séparateur de chemin standard dans HTTP selon la spécification.Réponses:
Puisque, d'après les commentaires publiés par l'OP, il semble qu'il ne veuille pas conserver les "URL absolues" dans la jointure (qui est l'une des tâches clés de
urlparse.urljoin
;-), je recommanderais d'éviter cela.os.path.join
serait également mauvais, pour exactement la même raison.Donc, j'utiliserais quelque chose comme
'/'.join(s.strip('/') for s in pieces)
(si le début/
doit également être ignoré - si le morceau principal doit être avec une casse spéciale, c'est également faisable bien sûr ;-).la source
os.path.join('http://media.com', 'content')
nous reviendronshttp://media.com\content
.Vous pouvez utiliser
urllib.parse.urljoin
:Mais attention :
La raison pour laquelle vous obtenez des résultats différents de
/js/foo.js
etjs/foo.js
est que le premier commence par une barre oblique qui signifie qu'il commence déjà à la racine du site Web.Sur Python 2, vous devez faire
la source
urljoin
supprime jamais «/». Si je l'appelle avecurlparse.urljoin('/media/', '/js/foo.js')
la valeur renvoyée est «/js/foo.js». Il a supprimé tous les médias, pas le double «/». En faiturlparse.urljoin('/media//', 'js/foo.js')
retourne en fait '/media//js/foo.js', donc aucun dupliqué supprimé.urljoin
n'est pas pour rejoindre des URL. C'est pour résoudre les URL relatives telles que trouvées dans les documents HTML, etc.Comme vous le dites,
os.path.join
joint les chemins en fonction du système d'exploitation actuel.posixpath
est le module sous-jacent qui est utilisé sur les systèmes posix sous l'espace de nomsos.path
:Ainsi, vous pouvez simplement importer et utiliser à la
posixpath.join
place des URL, qui sont disponibles et fonctionnent sur n'importe quelle plate-forme .Edit: La suggestion de @ Pete est bonne, vous pouvez alias l'importation pour une meilleure lisibilité
Edit: Je pense que cela est plus clair, ou du moins m'a aidé à comprendre, si vous regardez la source de
os.py
(le code ici est de Python 2.7.11, plus j'ai coupé quelques bits). Il y a des importations conditionnellesos.py
qui choisissent le module de chemin à utiliser dans l'espace de nomsos.path
. Tous les modules sous - jacents (posixpath
,ntpath
,os2emxpath
,riscospath
) qui peuvent être importés dansos.py
, comme aliasépath
, sont là et existent pour être utilisé sur tous les systèmes.os.py
choisit simplement l'un des modules à utiliser dans l'espaceos.path
de noms au moment de l'exécution en fonction du système d'exploitation actuel.la source
from posixpath import join as urljoin
l'alias joliment en quelque chose de facile à lire.Cela fait bien le travail:
la source
La fonction basejoin dans le package urllib peut être ce que vous recherchez.
Edit: Je n'avais pas remarqué avant, mais urllib.basejoin semble mapper directement à urlparse.urljoin, ce qui rend ce dernier préféré.
la source
En utilisant furl,
pip install furl
ce sera:la source
.url
à la fin:furl.furl('/media/path/').add(path='js/foo.js').url
furl('/media/path/').add(path=furl('/js/foo.js').path).url
parce quefurl('/media/path/').add(path='/js/foo.js').url
c'est/media/path//js/foo.js
Je sais que c'est un peu plus que ce que l'OP demandait, mais j'avais les pièces à l'url suivante et je cherchais un moyen simple de les rejoindre:
Faire quelques recherches:
Donc, en plus du chemin de jonction auquel on a déjà répondu dans les autres réponses, pour obtenir ce que je cherchais, j'ai fait ce qui suit:
Selon la documentation, il faut EXACTEMENT un tuple en 5 parties.
Avec le format de tuple suivant:
la source
Rune Kaagaard a fourni une solution géniale et compacte qui a fonctionné pour moi, je l'ai un peu développée:
Cela permet à tous les arguments d'être joints indépendamment des barres obliques de fin et de fin, tout en préservant la dernière barre oblique si elle est présente.
la source
return "/".join([str(x).strip("/") for x in args]) + trailing_slash
Pour améliorer légèrement la réponse d'Alex Martelli, ce qui suit permettra non seulement de nettoyer les barres obliques supplémentaires, mais également de préserver les barres obliques de fin (fin), ce qui peut parfois être utile:
Ce n'est pas aussi facile à lire cependant, et ne nettoiera pas plusieurs barres obliques supplémentaires.
la source
J'ai trouvé des choses qui ne me plaisaient pas dans toutes les solutions ci-dessus, alors j'ai proposé la mienne. Cette version s'assure que les pièces sont jointes avec une seule barre oblique et laisse seules les barres obliques de début et de fin. Non
pip install
, pas deurllib.parse.urljoin
bizarrerie.la source
Utilisation de furl et regex (python 3)
la source