2015-11-23 14 views
16

benim modülü bulamıyorum ve bu aşağıdaki yapıya sahiptir:Python I (Ben virtualenv içinde çalıştırın) bir piton projesi var

Project 
├───.git 
├───venv 
└───src 
    ├───__init__.py 
    ├───mymodules 
    │ ├───__init__.py 
    │ ├───module1.py 
    │ └───module2.py 
    └───scripts 
     ├───__init__.py 
     └───script.py 

script.py

import src.mymodules.module1 
... 

Projeyi aşağıdaki komutları kullanarak venv etkinleştirilmiş ve Project dizininden çalıştırıyorum:

(venv)$ python src/scripts/script.py 

komut çalıştırır ama çıkmadan önce aşağıdaki hatayı verir: Ben Python kabuğu çalışan ve oradan modülü almak için çalışıyor denedim ve hiçbir hata verdi

Traceback (most recent call last): 
    File "src/scripts/script.py", line 1, in <module> 
    import src.mymodules.module1 
ImportError: No module named src.mymodules.module1 

. Src içindeki her dizinde _ _init__.py var. Python, çalışma dizinini src/scripts olarak düşünüyor mu? Neden böyle oluyor ve bu durumda çalışma dizinini nasıl src yapabilirim?

+0

Python 2 veya 3? 3 paket modülü ithalatını farklı bir şekilde ele almaktadır. – Mego

+0

@Mego Python 2.7 – CrazyJony

+0

Bu yardımcı olabilir http://stackoverflow.com/questions/33773202/how-to-import-a-class-from-a-different-folder-in-python/33773635#33773635 –

cevap

10

Esasen, script.py'u doğrudan çalıştırdığınızda, bunun src alt modülünün bir parçası olduğunu bilmez ve src adlı bir modülün nerede olabileceğini bilmez. Bu, python 2 veya 3'teki durumdur.

Bildiğiniz gibi Python, sys.path içeriğine dayalı modülleri bulur. Herhangi bir modülü içe aktarmak için, ya sys.path'da listelenen bir dizinde ya da çalıştığınız komut dizisiyle aynı dizinde bulunmalıdır.

sen (yani script.py bulunduğu çünkü) python src/scripts/script.py, sys.pathProject/src/scripts/ içerdiğini varsayalım

ama Project. Project yolda olmadığından, bu dizindeki ( src) modüller içe aktarılamaz.

Bunu düzeltmek için: Ben senin script.py senin src modül için bir giriş noktası olduğunu varsayarak yaşıyorum

(örneğin, belki de ana program var).

Project 
├───.git 
├───venv 
|───script.py  <--- script.py moves up here 
└───src 
    ├───__init__.py 
    └───mymodules 
     ├───__init__.py 
     ├───module1.py 
     └───module2.py 

Bu şekilde, script.py serbestçe src şey alabilir, ama src hiçbir şey script.py alabilirsiniz: Eğer bu doğruysa, o zaman src aynı seviyeye kadar script.py hareket ettirerek düzeltmek.

$ python -m src.scripts.script 

sen söyledim Çünkü piton:

bu durumda değilse, ve script.py gerçekten src modül şöyle bir parçası olarak script.py yürütmek için Python en -m argüman kullanabilirsiniz src bir parçasıdır hangi modülü çalıştırıyorsunuz (src), yolda olacak. Yani, script.py, src alt modülünün farkında olacak ve src'dan içe aktarılabilecektir.

Bu durumda dikkatli olun - src öğesinde src.scripts.script öğesinin içe aktarılması durumunda döngüsel içe aktarma oluşturma potansiyeli vardır.


bu yaklaşımların her ikisi için bir alternatif olarak, script.py doğrudan sys.path değiştirebilirsiniz:

import sys 
sys.path.insert(0, '/path/to/Project') # location of src 

bu işe yararken, genellikle benim tercihi değil. Kodunuzun nasıl yerleştirildiğini tam olarak bilmek script.py'u gerektirir ve başka bir python programı script.py'u almaya çalıştığında içe aktarma karmaşasına neden olabilir.

+0

Teşekkürler, tüm 3 seçenek çalışıyor. İlki bu proje için bir seçenek değil. Üçüncü olan, belirttiğiniz sebepten dolayı çok zarif değil. Şimdilik, python -m src.scripts.script 'kullanacağımı düşünüyorum. Buradaki diğer sorularda da gördüğüm gibi, onu bir paket gibi yapılandırmanın yeterli olacağını düşündüm. – CrazyJony

+0

Python, çeşitli nedenlerle paketleri bulmak için "yukarı" dizin seviyelerine gitmiyor. Ve alt modüller kardeşleri ithal edebilir ve yapabilir, ancak çoğunlukla paketlerin kendi başlarına program olması gerekmeyen diğer programlar tarafından (ve bir sistem paket dizinine kurulur) kullanılması amaçlanır. Python'un bu kısmı kafa karıştırıcı olabilir, ama biraz mantıklı. – Seth

0
Project 
├───.git 
├───venv 
└───src 
    ├───__init__.py 
    ├───mymodules 
    │ ├───__init__.py 
    │ ├───module1.py 
    │ └───module2.py 
    └───scripts 
     ├───__init__.py 
     └───script.py 

Alternatif Artık herhangi bir yerden script.py dosyasını çalıştırabilirsiniz script.py

import os 
import sys 
sys.path.append(os.path.join(os.path.dirname(__file__),'../../')) 
import src.mymodules.module1 

aşağıdaki gibi alabilirsiniz.

e.g : 
python script.py 
python /path to folder/script.py