Saya mencoba belajar python dan saya membuat program yang akan menampilkan skrip. Saya ingin menggunakan os.path.join, tetapi saya cukup bingung. Menurut dokumen jika saya mengatakan:
os.path.join('c:', 'sourcedir')
Saya mengerti "C:sourcedir"
. Menurut dokumen, ini normal kan?
Tetapi ketika saya menggunakan perintah copytree, Python akan menampilkannya dengan cara yang diinginkan, misalnya:
import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)
Ini kode kesalahan yang saya dapatkan:
WindowsError: [Error 3] Sistem tidak dapat menemukan jalur yang ditentukan: 'C: src /*.*'
Jika saya membungkusnya os.path.join
dengan os.path.normpath
saya mendapatkan kesalahan yang sama.
Jika ini os.path.join
tidak bisa digunakan dengan cara ini, maka saya bingung untuk tujuannya.
Menurut halaman yang disarankan oleh Stack Overflow, garis miring tidak boleh digunakan dalam penggabungan — itu benar, menurut saya?
sumber
os.path.join
atauos.sep
jika Anda tetap akan menentukannyac:
?c:
tidak masuk akal di OS lain.os.path.join('c:','folder')
berfungsi secara berbedaos.path.join('folder','file')
? Apakah karena:
atau karena 'c: `adalah drive?Untuk lebih bertele-tele, jawaban yang paling konsisten dari python doc adalah:
mypath = os.path.join('c:', os.sep, 'sourcedir')
Karena Anda juga membutuhkan os.sep untuk jalur root posix:
mypath = os.path.join(os.sep, 'usr', 'lib')
sumber
os.sep
lebih unggul?os.sep
. Ini hanya berfungsi setelah huruf drive kosong. >>> os.path.join ("C: \ goodbye", os.sep, "temp") 'C: \\ temp'os.sep
berguna saat Anda ingin memanipulasi jalur tanpa membuat asumsi tentang pemisah. Tidak ada gunanya digunakan denganos.path.join()
karena sudah mengetahui pemisah yang tepat. Ini juga tidak ada gunanya jika Anda akhirnya perlu secara eksplisit menentukan direktori root berdasarkan nama (seperti yang Anda lihat di contoh Anda sendiri). Mengapa"c:" + os.sep
bukannya sederhana"c:\\"
, atauos.sep + "usr"
bukannya sederhana"/usr"
? Juga perhatikan bahwa di Win shells Anda tidak bisacd c:
tetapi Anda bisacd c:\
, menunjukkan bahwa nama root sebenarnyac:\
.Alasannya
os.path.join('C:', 'src')
tidak berfungsi seperti yang Anda harapkan adalah karena sesuatu di dokumentasi yang Anda tautkan:Seperti yang dikatakan anjing hantu, Anda mungkin menginginkannya
mypath=os.path.join('c:\\', 'sourcedir')
sumber
Untuk menjadi bertele-tele, mungkin tidak baik menggunakan hardcode baik / atau \ sebagai pemisah jalur. Mungkin ini yang terbaik?
mypath = os.path.join('c:%s' % os.sep, 'sourcedir')
atau
mypath = os.path.join('c:' + os.sep, 'sourcedir')
sumber
Untuk solusi sistem-agnostik yang bekerja pada Windows dan Linux, apa pun jalur inputnya, seseorang dapat menggunakannya
os.path.join(os.sep, rootdir + os.sep, targetdir)
Di Windows:
>>> os.path.join(os.sep, "C:" + os.sep, "Windows") 'C:\\Windows'
Di Linux:
>>> os.path.join(os.sep, "usr" + os.sep, "lib") '/usr/lib'
sumber
c:
tidak ada di * nix, danusr
tidak ada di windows ..os.path.join(os.sep, rootdir + os.sep, targetdir)
bersifat agnostik sistem karena ia bekerja dengan kedua contoh khusus sistem tersebut, tanpa perlu mengubah kodenya.rootdir = "usr" if nix else "c:"
. Tapi yang lebih langsung dan akuratrootdir = "/usr" if nix else "c:\\"
bekerja dengan baik, tanpaos.sep
akrobat dan garukan kepala berikutnya. Tidak ada bahaya bahwa direktori root pada * nix akan dimulai dengan apa pun selain garis miring, atau bahwa Windows akan memiliki direktori root yang diberi nama tanpa tanda titik dua dan garis miring terbalik (misalnya dalam kerangka Win, Anda tidak dapat melakukannya begitu sajacd c:
, Anda perlu menentukan garis miring terbalik), jadi mengapa berpura-pura sebaliknya?Saya akan mengatakan ini adalah bug python (windows).
Mengapa bug?
Saya pikir pernyataan ini seharusnya
True
Tapi itu ada
False
di mesin windows.sumber
untuk bergabung dengan jalur windows, coba
mypath=os.path.join('c:\\', 'sourcedir')
pada dasarnya, Anda harus menghindari garis miring
sumber
Anda memiliki beberapa kemungkinan pendekatan untuk menangani jalur di Windows, dari yang paling keras kode (seperti menggunakan literal string mentah atau garis miring terbalik) hingga yang paling kecil. Berikut ini beberapa contoh yang akan berfungsi seperti yang diharapkan. Gunakan apa yang lebih sesuai dengan kebutuhan Anda.
In[1]: from os.path import join, isdir In[2]: from os import sep In[3]: isdir(join("c:", "\\", "Users")) Out[3]: True In[4]: isdir(join("c:", "/", "Users")) Out[4]: True In[5]: isdir(join("c:", sep, "Users")) Out[5]: True
sumber
Setuju dengan @ georg-
Saya akan mengatakan mengapa kita membutuhkan orang lumpuh
os.path.join
- lebih baik digunakanstr.join
atauunicode.join
misalnyasys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))
sumber
menjawab komentar Anda: "yang lain '//' 'c:', 'c: \\' tidak berfungsi (C: \\ membuat dua garis miring terbalik, C: \ tidak berfungsi sama sekali)"
Pada jendela yang menggunakan
os.path.join('c:', 'sourcedir')
secara otomatis akan menambahkan dua garis miring terbalik\\
di depan sumber .Untuk menyelesaikan jalur, karena python berfungsi di windows juga dengan garis miring ke depan -> '/' , cukup tambahkan
.replace('\\','/')
denganos.path.join
seperti di bawah ini: -os.path.join('c:\\', 'sourcedir').replace('\\','/')
misalnya:
os.path.join('c:\\', 'temp').replace('\\','/')
keluaran: 'C: / temp'
sumber
Solusi yang diusulkan menarik dan menawarkan referensi yang baik, namun hanya sebagian yang memuaskan. Anda boleh menambahkan pemisah secara manual saat Anda memiliki kasus tertentu atau Anda mengetahui format string masukan, tetapi mungkin ada kasus di mana Anda ingin melakukannya secara terprogram pada masukan umum.
Dengan sedikit percobaan, saya yakin kriterianya adalah bahwa pembatas jalur tidak ditambahkan jika segmen pertama adalah huruf drive, yang berarti satu huruf diikuti oleh titik dua, tidak peduli apakah itu sesuai dengan unit nyata.
Sebagai contoh:
import os testval = ['c:','c:\\','d:','j:','jr:','data:'] for t in testval: print ('test value: ',t,', join to "folder"',os.path.join(t,'folder'))
Cara mudah untuk menguji kriteria dan menerapkan koreksi jalur dapat menggunakan
os.path.splitdrive
membandingkan elemen pertama yang dikembalikan ke nilai pengujian, sepertit+os.path.sep if os.path.splitdrive(t)[0]==t else t
.Uji:
for t in testval: corrected = t+os.path.sep if os.path.splitdrive(t)[0]==t else t print ('original: %s\tcorrected: %s'%(t,corrected),' join corrected->',os.path.join(corrected,'folder'))
itu mungkin dapat ditingkatkan menjadi lebih kuat untuk ruang tambahan, dan saya telah mengujinya hanya di windows, tapi saya harap ini memberi gambaran. Lihat juga Os.path: dapatkah Anda menjelaskan perilaku ini? untuk detail menarik tentang sistem selain jendela.
sumber