__init__.pyで定義されたクラスをインポートする方法


105

自分用にいくつかのモジュールを整理しようとしています。私はこのようなものを持っています:

lib/
  __init__.py
  settings.py
  foo/
    __init__.py
    someobject.py
  bar/
    __init__.py
    somethingelse.py

ではlib/__init__.py、libをインポートする場合に使用するいくつかのクラスを定義したいと思います。ただし、クラスをファイルに分けてにインポートしないと、それを理解できないようです__init__.py

言うよりも:

    lib/
      __init__.py
      settings.py
      helperclass.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib.helperclass import Helper

私はこのようなものが欲しい:

    lib/
      __init__.py  #Helper defined in this file
      settings.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib import Helper

それは可能ですか、またはクラスを別のファイルに分割する必要がありますか?

編集する

OK、別のスクリプトからlibをインポートすると、Helperクラスにアクセスできます。settings.pyからどのようにHelperクラスにアクセスできますか?

この例は、パッケージ内参照について説明しています。私は「サブモジュールはしばしば相互に参照する必要がある」と引用しています。私の場合、lib.settings.pyはHelperを必要とし、lib.foo.someobjectはHelperへのアクセスを必要とするので、Helperクラスをどこに定義すればよいですか?


あなたの最後の例はうまくいくはずです。ImportErrorが発生していますか?詳細を貼り付けてもらえますか?
Joe Holloway、

回答:


81
  1. ' lib/の親ディレクトリはにある必要がありますsys.path

  2. ' lib/__init__.py'は次のようになります:

    from . import settings # or just 'import settings' on old Python versions
    class Helper(object):
          pass

その後、次の例が機能するはずです。

from lib.settings import Values
from lib import Helper

質問の編集されたバージョンへの回答:

__init__.pyパッケージが外部からどのように見えるかを定義します。Helperin を使用する必要がある場合は、「」などの別のファイルでsettings.py定義Helperしますlib/helper.py

。
| `-import_submodule.py
    `-lib
    |-__init__.py
    |-foo
    | |-__init__.py
    | `-someobject.py
    |-helper.py
    `-settings.py

2つのディレクトリ、6つのファイル

コマンド:

$ python import_submodule.py

出力:

settings
helper
Helper in lib.settings
someobject
Helper in lib.foo.someobject

# ./import_submodule.py
import fnmatch, os
from lib.settings import Values
from lib import Helper

print
for root, dirs, files in os.walk('.'):
    for f in fnmatch.filter(files, '*.py'):
        print "# %s/%s" % (os.path.basename(root), f)
        print open(os.path.join(root, f)).read()
        print


# lib/helper.py
print 'helper'
class Helper(object):
    def __init__(self, module_name):
        print "Helper in", module_name


# lib/settings.py
print "settings"
import helper

class Values(object):
    pass

helper.Helper(__name__)


# lib/__init__.py
#from __future__ import absolute_import
import settings, foo.someobject, helper

Helper = helper.Helper


# foo/someobject.py
print "someobject"
from .. import helper

helper.Helper(__name__)


# foo/__init__.py
import someobject

この例のsettings.pyファイルにHelperクラスをインポートするにはどうすればよいですか?
scottm 2009

それが循環的である理由がわかりません。settings.pyがHelperを必要とし、foo.someobject.pyがHelperを必要とする場合、どこに定義することをお勧めしますか?
scottm 2009

うわー、その例では「ヘルパー」という言葉は本当に意味を失い始めています。しかし、あなたは私が探していたものを見せてくれました。
scottm 2009

3
「__init__.pyはパッケージが外部からどのように見えるかを定義します。」に賛成
ペトリ

19

lib/__init__.pyHelperクラスを定義している場合、settings.pyで次を使用できます。

from . import Helper

これは、は現在のディレクトリであり、設定モジュールの観点から見ると、libパッケージの同義語として機能します。を介してヘルパーをエクスポートする必要はないことに注意してください__all__

(Windowsで実行されているpython 2.7.10で確認されています。)


1
これは私にとってはうまく機能しています。反対投票者はあなたの不快感を説明してください
yoyo 2015

8

あなたはそれらを__init__.pyに置くだけです。

したがって、test / classes.pyは次のようになります。

class A(object): pass
class B(object): pass

...そしてtest / __ init__.pyは:

from classes import *

class Helper(object): pass

テストをインポートして、A、B、ヘルパーにアクセスできます

>>> import test
>>> test.A
<class 'test.classes.A'>
>>> test.B
<class 'test.classes.B'>
>>> test.Helper
<class 'test.Helper'>

どこからインポートしますか?
アーロン・メンパー09

lib / settings.pyからHelperをインポートしたいとしますか?
scottm 2009

1
これはほぼ確実に循環インポートになります(設定はテストをインポートし、テストは設定をインポートします)...これは、説明するNameErrorを生成します。パッケージ内で使用されるヘルパーが必要な場合は、コードが使用する内部モジュールを定義する必要があります。
アーロンメンパー09

1
init .pyのヘルパーは、外部ユーザーがAPIを簡略化するためのものです。
アーロンメンパー09

1
それがAPIの一部ではない場合、init .pyは実際にはその場所ではありません。lib / internal.pyまたは同様のものがはるかに優れています(循環インポートの可能性を減らすという二重の目的があります)。
アーロンメンパー09


4

編集、私が質問を誤解したので:

Helperクラスをに置くだけ__init__.pyです。それは完全にpythonicです。それは、Javaのような言語から来るのが奇妙に感じられるだけです。


あなたは誤解しました。可能であれば、helperClass.pyファイルを削除します。
scottm 2009

誤解されたのはリチャードだけではありません。あなたの例はうまくいくはずです。トレースバックとは何ですか?
トロイJ.ファレル

さて、それから私はドキュメントを正しく読みました。だから、今私はテストケースを作っただけでそれはうまくいきました。
scottm 2009

私のパッケージには同じ設定がありますが、ImportError "cannot import name Helper"が発生します
scottm

私の問題は、settings.pyからHelperクラスをインポートしようとしていることだと思いますが、どうすればそれができますか?
scottm 2009

2

はい、可能です。また、定義したいかもしれません__all____init__.pyファイル。これは、インポート時にインポートされるモジュールのリストです

from lib import *

-6

多分これはうまくいくかもしれません:

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