os.path
bekerja dengan cara yang lucu. Sepertinya os
harus paket dengan submodule path
, tetapi dalam kenyataannya os
adalah modul normal yang melakukan sihir dengan sys.modules
menyuntikkan os.path
. Inilah yang terjadi:
Ketika Python dimulai, ia memuat banyak modul ke dalamnya sys.modules
. Mereka tidak terikat dengan nama apa pun di skrip Anda, tetapi Anda dapat mengakses modul yang sudah dibuat saat Anda mengimpornya dengan cara tertentu.
sys.modules
adalah dict di mana modul di-cache. Ketika Anda mengimpor modul, jika sudah diimpor di suatu tempat, itu membuat instance disimpan sys.modules
.
os
adalah salah satu modul yang dimuat ketika Python dimulai. Ini menetapkan path
atributnya ke modul jalur os-spesifik.
Itu menyuntikkan sys.modules['os.path'] = path
sehingga Anda dapat melakukan " import os.path
" seolah-olah itu adalah submodule.
Saya cenderung menganggap os.path
sebagai modul yang ingin saya gunakan daripada sesuatu dalam os
modul , jadi meskipun itu bukan benar - benar sebuah submodul dari sebuah paket yang disebut os
, saya mengimpornya seperti itu adalah satu dan saya selalu melakukannyaimport os.path
. Ini konsisten dengan bagaimana os.path
didokumentasikan.
Kebetulan, struktur semacam ini mengarah ke banyak kebingungan awal programmer Python tentang modul dan paket dan organisasi kode, saya pikir. Ini benar-benar karena dua alasan
Jika Anda menganggap os
sebagai paket dan tahu bahwa Anda dapat melakukan import os
dan memiliki akses ke submodule os.path
, Anda mungkin akan terkejut ketika Anda tidak dapat melakukan import twisted
dan secara otomatis mengakses twisted.spread
tanpa mengimpornya.
Ini membingungkan bahwa itu os.name
adalah hal yang normal, string, dan os.path
merupakan modul. Saya selalu menyusun paket saya dengan __init__.py
file kosong sehingga pada tingkat yang sama saya selalu memiliki satu jenis hal: modul / paket atau hal-hal lain. Beberapa proyek Python besar mengambil pendekatan ini, yang cenderung membuat kode lebih terstruktur.
import os.path
sendiri dan berpikir itu cara yang lebih baik. Dengan "Ini konsisten dengan bagaimana os.path didokumentasikan" Maksud saya diberikan halamannya sendiri dalam dokumentasi di docs.python.org/library/os.path.html .os.py
memang menyuntikkan kesys.modules['os.path']
. Jadi inilah mengapafrom os.path import something
sebenarnya bekerja. Saya ingin tahu tentang kapan ini diperkenalkan dan memeriksa sumbernya. Fakta menyenangkan: Ini dari tahun 1999, pertama kali dimasukkan dalam Python 1.5.2. Komit asli ada di sini .Sesuai PEP-20 oleh Tim Peters, "Eksplisit lebih baik daripada implisit" dan "jumlah keterbacaan". Jika semua yang Anda butuhkan dari
os
modul berada di bawahos.path
,import os.path
akan lebih eksplisit dan biarkan orang lain tahu apa yang Anda benar-benar pedulikan.Demikian juga, PEP-20 juga mengatakan "Sederhana lebih baik daripada kompleks", jadi jika Anda juga membutuhkan barang-barang yang berada di bawah
os
payung yang lebih umum ,import os
akan lebih disukai.sumber
import os
sebenarnya menjadi "sederhana" dengan cara apa pun yang berarti. Sederhana! = Pendek.import os
dan sebuahimport os.path
adalah bodoh jika Anda misalnya kebutuhanos.getcwd()
danos.path.isfile()
Jawaban pasti:
import os
dan gunakanos.path
. janganimport os.path
langsung.Dari dokumentasi modul itu sendiri:
sumber
os.path
modul yang tidak ada, tetapi untukposixpath
."Instead of importing this module directly, import os and refer to this module as os.path."
tersebut berada diposixpath.py
(ataumacpath.py
,ntpath.py
dll.). Saya cukup yakin bahwa apa yang mereka maksud adalah bahwa seseorang tidak bolehimport posixpath
(yang bekerja), tetapi mengimpor modul viaos
untuk portabilitas yang lebih baik. Saya tidak berpikir mereka bermaksud untuk memberikan rekomendasi apakahimport os
atauimport os.path
lebih disukai.Yang cukup menarik, mengimpor os.path akan mengimpor semua os. coba yang berikut ini di prompt interaktif:
Hasilnya akan sama seperti jika Anda baru saja mengimpor os. Ini karena os.path akan merujuk ke modul berbeda berdasarkan sistem operasi yang Anda miliki, jadi python akan mengimpor os untuk menentukan modul mana yang akan dimuat untuk path.
referensi
Dengan beberapa modul, mengatakan
import foo
tidak akan mengeksposfoo.bar
, jadi saya kira itu sangat tergantung pada desain modul tertentu.Secara umum, hanya mengimpor modul eksplisit yang Anda butuhkan harus sedikit lebih cepat. Di mesin saya:
import os.path
:7.54285810068e-06
detikimport os
:9.21904878972e-06
detikWaktu-waktu ini cukup dekat sehingga bisa diabaikan. Program Anda mungkin perlu menggunakan modul lain dari
os
sekarang atau nanti, jadi biasanya masuk akal hanya mengorbankan dua mikrodetik dan gunakanimport os
untuk menghindari kesalahan ini di lain waktu. Saya biasanya berpihak dengan hanya mengimpor os secara keseluruhan, tetapi dapat melihat mengapa beberapa lebih suka secaraimport os.path
teknis lebih efisien dan menyampaikan kepada pembaca kode bahwa itu adalah satu-satunya bagian darios
modul yang perlu digunakan. Ini pada dasarnya bermuara pada pertanyaan gaya dalam pikiran saya.sumber
from os import path
akan membuat panggilan ke jalur lebih cepat jika kecepatan adalah masalah.Akal sehat bekerja di sini:
os
adalah modul, danos.path
juga modul. Jadi impor saja modul yang ingin Anda gunakan:Jika Anda ingin menggunakan fungsionalitas dalam
os
modul, maka imporos
.Jika Anda ingin menggunakan fungsionalitas dalam
os.path
modul, maka imporos.path
.Jika Anda ingin menggunakan fungsionalitas di kedua modul, maka impor kedua modul:
Sebagai referensi:
Lib / idlelib / rpc.py menggunakan
os
dan mengimporos
.Lib / idlelib / idle.py menggunakan
os.path
dan mengimporos.path
.Lib / ensurepip / init .py menggunakan keduanya dan mengimpor keduanya.
sumber
Tidak dapat menemukan referensi pasti, tetapi saya melihat bahwa contoh kode untuk os.walk menggunakan os.path tetapi hanya mengimpor os
sumber