Misalnya, saya ingin bergabung dengan jalur awalan ke jalur sumber daya seperti /js/foo.js.
Saya ingin jalur yang dihasilkan relatif terhadap root server. Dalam contoh di atas, jika awalannya adalah "media", saya ingin hasilnya menjadi /media/js/foo.js.
os.path.join melakukan ini dengan sangat baik, tetapi cara bergabung dengan jalur bergantung pada OS. Dalam hal ini saya tahu saya menargetkan web, bukan sistem file lokal.
Apakah ada alternatif terbaik saat Anda bekerja dengan jalur yang Anda tahu akan digunakan di URL? Akankah os.path.join bekerja dengan cukup baik? Haruskah saya menggulung sendiri?
os.path.join
tidak akan berfungsi. Tetapi hanya bergabung dengan/
karakter harus berfungsi dalam semua kasus -/
adalah pemisah jalur standar di HTTP sesuai spesifikasi.Jawaban:
Karena, dari komentar yang diposting OP, sepertinya dia tidak ingin mempertahankan "URL absolut" saat bergabung (yang merupakan salah satu tugas utama
urlparse.urljoin
;-), saya sarankan untuk menghindari itu.os.path.join
juga buruk, karena alasan yang persis sama.Jadi, saya akan menggunakan sesuatu seperti
'/'.join(s.strip('/') for s in pieces)
(jika bagian depan/
juga harus diabaikan - jika bagian utama harus menggunakan kasing khusus, tentu saja itu juga layak ;-).sumber
os.path.join('http://media.com', 'content')
wourd kembalihttp://media.com\content
.Anda dapat menggunakan
urllib.parse.urljoin
:Namun berhati-hatilah :
Alasan Anda mendapatkan hasil yang berbeda dari
/js/foo.js
danjs/foo.js
karena yang pertama dimulai dengan garis miring yang menandakan bahwa hasil tersebut sudah dimulai di root situs web.Di Python 2, Anda harus melakukannya
sumber
urljoin
pernah menghapus '/'. Jika saya menyebutnya denganurlparse.urljoin('/media/', '/js/foo.js')
nilai yang dikembalikan adalah '/js/foo.js'. Ini menghapus semua media, bukan duplikat '/'. Bahkanurlparse.urljoin('/media//', 'js/foo.js')
sebenarnya mengembalikan '/media//js/foo.js', jadi tidak ada duplikat yang dihapus.urljoin
bukan untuk bergabung dengan URL. Itu untuk menyelesaikan URL relatif seperti yang ditemukan dalam dokumen HTML, dll.Seperti yang Anda katakan,
os.path.join
bergabung dengan jalur berdasarkan os saat ini.posixpath
adalah modul dasar yang digunakan pada sistem posix di bawah namespaceos.path
:Jadi Anda bisa mengimpor dan menggunakan
posixpath.join
url, yang tersedia dan akan berfungsi di platform apa pun .Edit: Saran @ Pete bagus, Anda bisa alias impor untuk meningkatkan keterbacaan
Sunting: Saya pikir ini dibuat lebih jelas, atau setidaknya membantu saya memahami, jika Anda melihat ke dalam sumber
os.py
(kode di sini adalah dari Python 2.7.11, ditambah saya telah memangkas beberapa bit). Ada impor bersyaratos.py
yang memilih modul jalur mana yang akan digunakan di namespaceos.path
. Semua modul yang mendasari (posixpath
,ntpath
,os2emxpath
,riscospath
) yang dapat diimpor dalamos.py
, alias sepertipath
, ada dan eksis untuk digunakan pada semua sistem.os.py
hanya memilih salah satu modul untuk digunakan di namespaceos.path
pada waktu proses berdasarkan OS saat ini.sumber
from posixpath import join as urljoin
dengan baik menyamakannya dengan sesuatu yang mudah dibaca.Ini melakukan pekerjaan dengan baik:
sumber
Fungsi basejoin dalam paket urllib mungkin yang Anda cari.
Sunting: Saya tidak memperhatikan sebelumnya, tetapi urllib.basejoin tampaknya memetakan langsung ke urlparse.urljoin, membuat yang terakhir lebih disukai.
sumber
Menggunakan furl,
pip install furl
itu akan menjadi:sumber
.url
di akhir:furl.furl('/media/path/').add(path='js/foo.js').url
furl('/media/path/').add(path=furl('/js/foo.js').path).url
karenafurl('/media/path/').add(path='/js/foo.js').url
adalah/media/path//js/foo.js
Saya tahu ini sedikit lebih dari yang diminta OP, Namun saya memiliki potongan ke url berikut, dan sedang mencari cara sederhana untuk bergabung dengan mereka:
Melakukan beberapa melihat sekeliling:
Jadi selain penggabungan jalur yang telah dijawab di jawaban lain, Untuk mendapatkan apa yang saya cari saya lakukan sebagai berikut:
Menurut dokumentasi yang dibutuhkan PERSIS 5 bagian tupel.
Dengan format tuple berikut:
sumber
Rune Kaagaard memberikan solusi hebat dan ringkas yang berhasil untuk saya, saya mengembangkannya sedikit:
Ini memungkinkan semua argumen untuk digabungkan, terlepas dari garis miring di akhir dan di akhir sambil mempertahankan garis miring terakhir jika ada.
sumber
return "/".join([str(x).strip("/") for x in args]) + trailing_slash
Untuk sedikit meningkatkan respons Alex Martelli, berikut ini tidak hanya akan membersihkan garis miring ekstra tetapi juga mempertahankan garis miring (akhir) garis miring, yang terkadang berguna:
Ini tidak semudah membaca, dan tidak akan membersihkan beberapa garis miring tambahan.
sumber
Saya menemukan hal-hal yang tidak disukai tentang semua solusi di atas, jadi saya datang dengan solusi saya sendiri. Versi ini memastikan bagian-bagian digabungkan dengan satu garis miring dan meninggalkan garis miring di depan dan di belakang saja. Tidak
pip install
, tidak adaurllib.parse.urljoin
keanehan.sumber
Menggunakan furl dan regex (python 3)
sumber