Tidak dapat mengimpor modul saya sendiri dengan Python

141

Saya mengalami kesulitan memahami cara pengimporan modul bekerja dengan Python (Saya belum pernah melakukannya dalam bahasa lain sebelumnya).

Katakanlah saya punya:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

Sekarang saya mencoba untuk mendapatkan sesuatu seperti ini:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

Namun, saya pasti melakukan sesuatu yang salah karena Python tidak dapat melihat itu myappadalah modul:

ImportError: No module named myapp
n0pe
sumber

Jawaban:

96

Dalam kasus khusus Anda, sepertinya Anda mencoba mengimpor SomeObjectdari skrip myapp.py dan TestCase.py. Dari myapp.py, lakukan

import SomeObject

karena berada di folder yang sama. Untuk TestCase.py, lakukan

from ..myapp import SomeObject

Namun , ini hanya akan berfungsi jika Anda mengimpor TestCase dari paket. Jika Anda ingin langsung lari python TestCase.py, Anda harus mengacaukan jalan Anda. Ini bisa dilakukan dalam Python:

import sys
sys.path.append("..")
from myapp import SomeObject

meskipun itu umumnya tidak dianjurkan.

Secara umum, jika Anda ingin orang lain menggunakan paket Python Anda, Anda harus menggunakan distutils untuk membuat skrip pengaturan. Dengan begitu, siapa pun dapat menginstal paket Anda dengan mudah menggunakan perintah seperti python setup.py installdan itu akan tersedia di mana-mana di mesin mereka. Jika Anda serius tentang paket, Anda bahkan bisa menambahkannya ke Indeks Paket Python, PyPI .

David Robinson
sumber
Saya mencoba hanya menggunakan tetapi importsaya TestCase.pymasih memberi saya kesalahan yang sama. Saya berasumsi itu karena ada di dalam sub-direktori __init__.py?
n0pe
Oh, tunggu, saya rasa saya mengerti. Jika kotak pengujian saya memanggil dari paket, saya akan dapat menggunakan from ... import ...hak?
n0pe
1
Anda hanya akan melakukannya jika TestCase diimpor dari luar paket - misalnya, jika saya menjalankan from myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` dalam folder tes yang tidak dapat Anda lakukan impor relatif
David Robinson
1
Saya menjalankan "pip install -e." Untuk menginstal myapp, tetapi ketika mencoba menjalankan TestCase dalam kode visual studio saya masih mendapatkan "ImportError: Tidak ada modul bernama myapp". tetapi jika saya menjalankan "python" dan kemudian dalam python run "dari myapp import SomeObject" itu berfungsi. Apa yang saya lakukan salah?
dagrun
@ DavidVobinson Saya menggunakan metode yang telah Anda sebutkan, yang menunjukkan tidak ada kesalahan setelah dieksekusi from fodername import file_name_of_my_py_code, tetapi ketika saya mencoba mengakses objek yang didefinisikan di file_name_of_my_py_code.pydalamnya dikatakanNameError: name 'ClassName' is not defined
Kavin Raju S
44

Fungsi importmencari file ke dalam PYTHONPATH Anda. variabel dan direktori lokal Anda. Jadi Anda bisa meletakkan semua file Anda di direktori yang sama, atau mengekspor path mengetik ke terminal ::

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"
Zenon
sumber
2
Lalu bagaimana saya bisa memastikan itu bekerja untuk semua orang yang akan menggunakannya? Saya lebih suka tidak memberitahu mereka untuk mengatur variabel lingkungan tertentu sebelum menjalankannya.
n0pe
1
direktori saat ini adalah di pythonpath, jadi selama skrip berada di folder / direktori yang sama itu harus berfungsi. sayangnya masing-masing skrip ini berada di direktori yang terpisah.
JKirchartz
4
Untuk pengguna Windows, alih-alih exportkami telah "mengatur PYTHONPATH =% PYTHONPATH%; C: \ path_to_myapp \ myapp \ myapp \"
loved.by.Jesus
Dalam vs kode saya dapat memperbaikinya dengan menambahkan variabel PYTHONPATH Env ke launch.json saya: "env": {"PYTHONPATH": "$ {workspaceFolder}"}
Michael Armitage
11

jalur ekspor adalah cara yang baik. Cara lain adalah menambahkan .pth ke lokasi paket situs Anda. Di mac saya, python saya menyimpan paket situs di / Library / Python di bawah ini

/Library/Python/2.7/site-packages

Saya membuat file bernama awesome.pth di /Library/Python/2.7/site-packages/awesome.pth dan dalam file tersebut letakkan path berikut ini yang mereferensikan modul mengagumkan saya

/opt/awesome/custom_python_modules
jmontross
sumber
1
dalam kasus saya bekerja di windows bagaimana saya melakukannya
Nwawel A Iroume
Saya tidak yakin. Jika Anda menggunakan windows. Temukan beberapa perangkat lunak vm dan gunakan linux. Atau - lihat jawaban ini tentang mengekspor variabel di windows. stackoverflow.com/questions/559816/…
jmontross
inilah tepatnya yang saya butuhkan
Lee88
1
Senang mendengarnya @ Lee88 - butuh waktu beberapa saat untuk mencari tahu sendiri :)
jmontross
9

Anda dapat mencoba

from myapp.myapp import SomeObject

karena nama proyek Anda sama dengan myapp.py yang membuatnya mencari dokumen proyek terlebih dahulu

阿 东 刘
sumber
3

Di direktori myapp pertama Anda, Anda dapat menambahkan file setup.py dan menambahkan dua kode python di setup.py

from setuptools import setup
setup(name='myapp')

di direktori myapp pertama Anda di commandline, gunakan pip install -e. untuk menginstal paket

未来 陆家嘴 顶尖 的 投资 人
sumber
2

pip installpada Windows 10 default untuk menginstal di 'Program Files / PythonXX / Lib / situs-paket' yang merupakan direktori yang memerlukan hak administratif. Jadi saya memperbaiki masalah saya dengan menjalankan pip install sebagai Administrator (Anda harus membuka command prompt sebagai administrator bahkan jika Anda masuk dengan akun admin). Juga, lebih aman untuk memanggil pip dari python.
misalnya
python -m pip install <package-name>
bukannya
pip install <package-name>

sziraqui
sumber
0

Dalam kasus saya itu adalah kejutan Windows vs Python, meskipun nama file Windows tidak sensitif huruf, impor Python adalah. Jadi, jika Anda memiliki Stuff.pyfile, Anda perlu mengimpor nama ini apa adanya.

astrowalker
sumber
0

Anda harus punya

__init__.py

di semua folder yang memiliki kode yang perlu Anda berinteraksi. Anda juga perlu menentukan nama folder teratas proyek Anda di setiap impor bahkan jika file yang Anda coba impor berada pada level yang sama.

Krysalead
sumber