Bagaimana cara menambahkan modul Python ke syspath?

69

Saya memiliki struktur file seperti ini:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Saya ingin mengimpor masuk foo2.py dan foo1.py. Saya mencoba tetapi tidak berfungsi di Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py
pengguna284474
sumber
Apakah Anda memiliki __init__.pyfile di folder Anda? ini adalah cara python membuat paket dan memungkinkan Anda untuk mengimpor modul dari paket itu. guide.python-distribute.org/creation.html
Bryan
Saya memiliki file init.py di Umum dan di TestFolder
user284474
Anda memerlukannya di direktori Folder serta di sub folder jika Anda ingin mengimpor
Bryan
Ini init py kosong?
user284474
1
ya itu bisa kosong. Kecuali jika Anda memerlukan konfigurasi tertentu untuk paket Anda, tetapi Anda akan baik-baik saja dengan itu menjadi kosong
Bryan

Jawaban:

115

Bagaimana python menemukan modul-modulnya

Modul yang diambil dengan ketat, adalah file python tunggal, sedangkan paket adalah folder yang berisi file python, disertai dengan file (bisa kosong) bernama __init__.py, untuk memberi tahu python itu adalah paket untuk mengimpor modul dari. Dalam kedua kasus, modul memerlukan .pyekstensi mereka , tetapi mengimpornya dilakukan tanpa (lihat lebih lanjut di bawah).

Secara default, Python mencari modul dan paketnya di $PYTHONPATH.

Untuk mengetahui apa yang termasuk dalam $ PYTHONPATH, jalankan kode berikut dalam python (3):

import sys
print(sys.path)

Cara menambahkan direktori

Kadang

Dari dalam file python, Anda dapat menambahkan path sesekali ke path default dengan menambahkan baris berikut di bagian kepala aplikasi atau skrip python Anda:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Sebagai contoh:

jika saya memiliki folder:, /home/myname/pythonfilesdan saya ingin mengimpor file module_1.py, terletak di direktori itu, saya menambahkan ini ke bagian kepala kode saya:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

Dan saya cukup mengimpor file module_1.pydengan:

import module_1

Ketika saya membuat paket dan ingin mengimpor modul dari paket, saya harus membuat folder $PYTHONPATH, berisi modul, disertai dengan file (dapat kosong) yang disebut__init__.py

Sebagai contoh:

Untuk mengimpor dari paket (folder) yang disebut my_packagedalam /home/myname/pythonfiles, tambahkan /home/myname/pythonfilespath ke Anda $PYTHONPATH, seperti dalam contoh 1, dan mengimpor modul yang disebut module_2.py(dalam folder paket) hanya dengan: `

from <packagename> import module_2

Menambahkan direktori ke $PYTHONPATHsecara permanen:

Tambahkan baris berikut ke ~/.profilefile Anda .

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Subdirektori

Dari dalam suatu paket, subdirektori tidak dimasukkan begitu saja; Anda perlu "rantai" direktori. Untuk mengimpor modul module_3.py, folder subfolderdi dalam folder packagename:

import packagename.subfolder.module_3

Mengingat fakta bahwa semua subfolder dalam paket menyertakan __init__.pyfile mereka sendiri .

Ketika sebuah modul berada di direktori yang sama dengan skrip atau aplikasi

Tidak perlu menyisipkan jalur ke modul ketika berada di direktori yang sama dengan skrip atau aplikasi, secara otomatis ditambahkan.

Contoh:

Jika saya memiliki folder, berisi script.pydan module.py, saya cukup mengimpor modul dengan:

import module
Yakub Vlijm
sumber
Saya juga ingin menyarankan membaca python.org/dev/peps/pep-0328 , khususnya jika Anda menargetkan Python 3 (atau berencana untuk menargetkan di masa depan)
zaadeh
Kenapa printenv PYTHONPATHtidak ada apa - apa?
Stevie G
1
sys.path.append("/path/to/your/package_or_module")juga menambahkan jalur ke default dan itu kurang membingungkan. Dibandingkan dengan sys.path.insert(0,...)yang memiliki 0argumen pertama.
Paul Rougieux
1
@PaulRougieux: Masalah dengan menambahkan ke jalan adalah bahwa modul Anda mungkin sudah ada di tempat lain di jalan (dalam file .egg misalnya) dan Anda akan mengambil bahwa versi modul Anda bukan satu dalam file Anda.
snark
6

Cara yang benar untuk menggunakan impor relatif adalah:

from ..Common import foo1

Dan Anda juga membutuhkan __init__.pydi semua folder Anda.

Sylvain Pineau
sumber
1
Terima kasih. Tetapi jika saya memiliki modul yang merupakan dua folder ke atas, bagaimana cara mengimpor itu? dari .... Folder tidak berfungsi
user284474
Apakah ini bekerja dengan satu level?
Sylvain Pineau
Dengan satu level ia berfungsi.
user284474
ok, bisakah kamu menerima jawaban ini? untuk multilevel meskipun Anda bisa mengajukan pertanyaan yang berbeda tetapi pertama-tama lihatlah pertanyaan ini dan jawaban ini untuk cara terbaik memanggil modul Anda di dalam sebuah paket
Sylvain Pineau
Apakah ini berlaku untuk Python 2 atau Python 3? Atau keduanya?
alex
2

NB: Jawaban ini sudah usang untuk versi terbaru dari python 3, tetapi ada di sini untuk versi sebelumnya. Untuk informasi lebih lanjut, baca komentar dan https://www.python.org/dev/peps/pep-0420/


Pada dasarnya setiap folder dengan kode python yang ingin Anda tambahkan ke syspath memerlukan file __init__.py. File __init__.py ini dapat kosong.

jangan
sumber
Seperti yang saya pahami, ini bukan lagi masalahnya, direktori sekarang menjadi "namespace".
Aaron Hall
@ Harun, menarik?
don.joey
1
Coba ini sebagai bukti: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"berikut ini juga beberapa dokumentasi yang relevan, PEP 420, yang menjelaskan penambahan semantik paket namespace
Aaron Hall