Pythonを別のフォルダからインポートできません


90

Pythonにモジュールをサブフォルダーにインポートさせることができないようです。インポートされたモジュールからクラスのインスタンスを作成しようとするとエラーが発生しますが、インポート自体は成功します。これが私のディレクトリ構造です:

Server
    -server.py
    -Models
        --user.py

server.pyの内容は次のとおりです。

from sys import path
from os import getcwd
path.append(getcwd() + "\\models") #Yes, i'm on windows
print path
import user

u=user.User() #error on this line

そしてuser.py:

class User(Entity):
    using_options(tablename='users')

    username = Field(String(15))
    password = Field(String(64))
    email    = Field(String(50))
    status   = Field(Integer)
    created  = Field(DateTime)

エラーは次のとおりです:AttributeError: 'module' object has no attribute 'User'


1
エラーメッセージを貼り付けることができますか?
Harley Holcombe

user.pyからの場合、server.pyをインポートします。私は何をしますか?
Chandra Kanth

回答:


139

__init__.pyPythonがそれをモジュールとして扱うように、Modelsディレクトリに呼び出されるファイルを作成する必要があると思います。

その後、次のことができます。

from Models.user import User

__init__.py(たとえば、いくつかの異なるクラスが必要とする初期化コード)にコードを含めるか、空白のままにすることができます。しかし、それはそこにあるに違いありません。


2
おかげで、これまでパッケージについて聞いたことがありませんでした。
ライガイ09年

1
実際、Pythonをインポートすると、blah.pyとblah / __ init__.pyはまったく同じように扱われます。
pi。

2
それは自明ではなかった...そして私は自分にこう言います:RTFM FMF
Alexander.Iljushkin

1
別のディレクトリからserver.pyを実行している場合、これは機能しないことに注意してください。
kchoi

1
server.pyが別のフォルダーにある場合はどうなりますか?
Mandroid

24

あなたは、作成する必要が__init__.pyModelsサブフォルダます。ファイルが空である可能性があります。パッケージを定義します。

その後、次のことができます。

from Models.user import User

すべてについては、こちらの pythonチュートリアルをご覧ください

こちらには、Pythonプロジェクトのファイル編成に関する優れた記事もあります


ファイルが空でない場合はどうなりますか?
darkgaze

12

ユーザーをインポート

u = user.User()#この行のエラー

上記の__init__がないため、問題をより明確にするImportErrorが予期されます。

'user'は標準ライブラリの既存のモジュールでもあるため、取得できません。あなたのインポートステートメントはそれを取得し、その中のUserクラスを見つけようとします。それは存在せず、それで初めてエラーが発生します。

一般に、インポートを絶対的にすることをお勧めします。

import Server.Models.user

この種のあいまいさを避けるために。実際、Python 2.7からは、「ユーザーのインポート」は現在のモジュールに対してまったく見えません。

相対インポートが本当に必要な場合は、Python 2.5以降でやや醜い構文を使用して明示的にインポートできます。

from .user import User

9

標準パッケージ構造がない場合に、親フォルダーにあるモジュールをインポートする正しい方法は次のとおりです。

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

(最後の2行をマージすることもできますが、この方法の方が簡単です)。

このソリューションはクロスプラットフォームであり、他の状況で変更する必要がないほど一般的です。


7

__init__.pyがありません。Pythonチュートリアルから:

__init__.pyファイルは、Pythonがディレクトリをパッケージを含むものとして扱うようにするために必要です。これは、文字列などの一般的な名前のディレクトリが、後でモジュール検索パスで発生する有効なモジュールを誤って非表示にしないようにするために行われます。最も単純な場合、__ init__.pyは空のファイルにすることができますが、パッケージの初期化コードを実行したり、後で説明する__all__変数を設定したりすることもできます。

__init__.pyという名前の空のファイルをModelsディレクトリに配置すると、すべてゴールデンになるはずです。


1

パラメータos.path.dirname....コマンドをどのように書き出すのですか?

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

0

私の好ましい方法は、他のモジュールで使用されるモジュールを含むすべてのディレクトリに__init__.pyを置き、エントリポイントでsys.pathを次のようにオーバーライドすることです。

def get_path(ss):
  return os.path.join(os.path.dirname(__file__), ss)
sys.path += [
  get_path('Server'), 
  get_path('Models')
]

これにより、指定したディレクトリ内のファイルがインポート用に表示され、Server.pyからユーザーをインポートできます。


0

上記のこれらの寄稿者からの回答を調べた後-Zorglub29、トム、マーク、アーロンマクミリン、lucasamaral、JoeyZhao、Kjeld Flarup、Procyclinsur、martin.zaenker、tooty44をしていた問題をデバッグしたところ、別のユースケースが見つかった私はこの問題に直面していました。したがって、誰かの参考のために以下に私の観察を追加します。

私のコードでは、クラスの循環インポートがありました。例えば:

src
 |-- utilities.py (has Utilities class that uses Event class)  
 |-- consume_utilities.py (has Event class that uses Utilities class)
 |-- tests
      |-- test_consume_utilities.py (executes test cases that involves Event class)

test_utilities.pyで記述されたUT を実行するためにpython -m pytest tests / test_utilities.pyを実行しようとすると、次のエラーが発生しました。

ImportError while importing test module '/Users/.../src/tests/test_utilities.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_utilities.py:1: in <module>
    from utilities import Utilities
...
...
E   ImportError: cannot import name 'Utilities'

エラーを解決する方法は、コードをリファクタリングして、循環インポートクラスの機能を移動し、クラスの循環インポートを削除できるようにすることでした。

__init__.py' src 'フォルダーと ' tests 'フォルダーにファイルがありますが、それでも ' ImportErrorを取り除くことができました。、コードをリファクタリングするだけで '。

以下のstackoverflowリンクは、Pythonの循環依存関係の詳細を提供します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.