2016-03-20 41 views
1

私はDjangoプロジェクトに取り組んでおり、作成したアプリケーションのURLConfを設定しようとしています。ここでは(あなたが本当に私の問題を理解するためにはDjangoを理解する必要はありません)Pythonがモジュールをインポートできません

は私のプロジェクトの関連部分

/PROJECT 
    __init__.py 
    settings.py 
    urls.py 
/home 
    __init__.py 
    views.py 
/user 
    __init__.py 
    views.py 

ある私はPROJECT/urls.pyからhomeをインポートしようとしています:

PROJECT/urls.py (relevant parts) 

from django.conf.urls import url, include 
from django.contrib import admin 
import user 
import home # <--- 

urlpatterns = [ 
    url(r'^$', home.views.index, name='index'), # <--- 
    url(r'^register/$', user.views.register, name='register'), 
    url(r'^login/$', user.views.login, name='login'), 
    url(r'^logout/$', user.views.logout, name='logout'), 
] 

なんらかの理由で、userをインポートしますが、インポート中はhome(およびそのサブモジュール)

私はDjangoのWebサーバで構築を実行すると、私はエラーを取得する:

AttributeError: module 'home' has no attribute 'views' 

私はuserとそのサブモジュール

をインポートするため、このエラーを取得しないん私はurls.pyを実行したときに、私はあることに注意する必要があり通常のPythonシェルでは、homeuserのインポートエラーが返されますが、DjangoのWebサーバーを実行するとエラーはhomeになります。私のコードのuserの部分は初めから正常に動作していて、通常のシェルではエラーが発生すると想定しています。

また、何らかの理由で、userは正しくインポートされませんが、homeは間違っていません。

これは、この使用のPython 3.5.1とDjango 1.9で

+0

どのPythonのバージョンですか? Python2には、意図したものの代わりに取得しているかもしれない 'user'モジュールがあります。 –

+0

Python 3.5、申し訳ありませんが、 – 99lives

+1

エラーから判断して、 'home'モジュール*はインポートされていますが、おそらくあなたが望むものではありません。 'home 'がどこからロードされたかを確認するには' print home'を使います。 – user4815162342

答えて

0

です:あなたがPythonでパッケージをインポートすると、それは再帰的にそれに含まれるそのサブパッケージまたはすべてのモジュールをインポートしません

import home.views 

を。

import userが機能する理由は明らかではありませんが、user/__init__.pyのビューをインポートしている可能性があります。それを避けて、別のモジュールがurl呼び出しでアクセスされる前にuser.viewsをインポートすることも可能です。これにより、Pythonはviewsモジュールをuserパッケージの名前空間に挿入します。あなたが見ることができるように、それはbを挿入する副作用があったので、mod_cをインポートする前に、そこmod_b内部は何もなかったが、それは一度mod_cを変えたが、輸入された

/tmp/importtest $ mkdir mod_a mod_b 
/tmp/importtest $ touch mod_{a,b}/__init__.py 
/tmp/importtest $ echo 'A=1' > mod_a/a.py 
/tmp/importtest $ echo 'B=2' > mod_b/b.py 
/tmp/importtest $ echo 'import mod_b.b' > mod_c.py 
/tmp/importtest $ python 
Python 3.4.3 (default, Jan 4 2016, 22:02:53) 
[GCC 4.9.3] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mod_a, mod_b 
>>> mod_a.a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'module' object has no attribute 'a' 
>>> mod_b.b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'module' object has no attribute 'b' 
>>> import mod_c 
>>> mod_b.b 
<module 'mod_b.b' from '/tmp/importtest/mod_b/b.py'> 
>>> mod_a.a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'module' object has no attribute 'a' 
>>> 

は、次の例を考えてみましょうオブジェクトをmod_bという名前空間に追加します。

これはこれをより明確にしますか?結論として

あなたがuser.viewshome.viewsにアクセスする場合は、常にちょうどトップレベルのパッケージをインポートし、他の何かがちょうどいいの副作用を持つことが起こることを期待するのではなく、user.viewshome.viewsをインポートします。

+0

ありがとう、これは動作します。 しかし、なぜユーザーは正しく動作していますか? user/__ init__.pyが空です – 99lives

+0

私はdownvoteを理解していません。答えは関連性があり、正確で、明確で、OPの問題を解決します。 Pythonを初めて使う人には、パッケージをインポートすると自動的にそのサブモジュールがインポートされないことは明らかではありません。 – user4815162342

+0

追加情報をありがとう。私はuser.viewsが他のものによってインポートされているとは思わないが、私は自分の時間にその研究を行うだろう。もう一度おねがいします – 99lives

0

共通の解決策は、homeフォルダをPython環境に追加することです。

# in your Django settings 
import os 
import sys 

PROJECT_DIR = os.path.dirname(os.path.dirname(__file__)) 
BASE_DIR = os.path.dirname(PROJECT_DIR) 

# add here 
sys.path.append(os.path.join(PROJECT_DIR, "home")) 

# now you can use home 
from home import view 

また、python2とpython3の相対インポートは、異なる動作をします。

関連する問題