質問

Pythonソースディレクトリでの__init__.pyとは何ですか

役に立ちましたか?

解決

以前はパッケージの必須部分でした( old、pre -3.3 <!> quot;通常のパッケージ<!> quot; 新しい3.3+ <!> quot; namespace package <!> quot; )。

こちらのドキュメント

  

Pythonは、通常のパッケージと名前空間パッケージの2種類のパッケージを定義します。通常のパッケージは、Python 3.2以前に存在していた従来のパッケージです。通常、通常のパッケージは、__init__.pyファイルを含むディレクトリとして実装されます。通常のパッケージがインポートされると、この<=>ファイルは暗黙的に実行され、定義するオブジェクトはpackage <!>#8217; s名前空間の名前にバインドされます。 <=>ファイルには、他のモジュールに含めることができるPythonコードと同じPythonコードを含めることができます。Pythonは、インポート時にモジュールに属性を追加します。

ただし、リンクをクリックするだけで、例、詳細情報、名前空間パッケージの説明、<=>のないパッケージの種類が含まれます。

他のヒント

__init__.pyという名前のファイルは、ディスク上のディレクトリをPythonパッケージディレクトリとしてマークするために使用されます。 ファイルがある場合

mydir/spam/__init__.py
mydir/spam/module.py

およびmydirがパス上にある場合、module.pyのコードを次のようにインポートできます

import spam.module

または

from spam import module

<=>ファイルを削除すると、Pythonはそのディレクトリ内のサブモジュールを検索しなくなるため、モジュールのインポートは失敗します。

通常、<=>ファイルは空ですが、パッケージの選択した部分をより便利な名前でエクスポートしたり、便利な機能を保持したりするために使用できます。 上記の例では、initモジュールのコンテンツには

としてアクセスできます
import spam

this

に基づく

ディレクトリをPythonパッケージとしてラベル付けし、__all__を定義することに加えて、 __init__.pyを使用すると、パッケージレベルで任意の変数を定義できます。パッケージで何かを定義する場合、便利です。 APIのように頻繁にインポートされます。このパターンは、Pythonic <!> quot; flatはネストされた<!> quotよりも優れています。哲学。

これは、私のプロジェクトの1つの例です。ここでは、データベースと対話するためにsessionmakerというSessionを頻繁にインポートしています。 <!> quot; database <!> quot;を書きました。いくつかのモジュールを含むパッケージ:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

My <=>には次のコードが含まれています:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

ここで<=>を定義しているため、以下の構文を使用して新しいセッションを開始できます。このコードは、<!> quot; database <!> quotの内部または外部から実行されるものと同じです。パッケージディレクトリ。

from database import Session
session = Session()

もちろん、これはちょっとした便利さです-代替案は<=> quot; create_session.py <!> quot;のような新しいファイルで<=>を定義することです。データベースパッケージで、次を使用して新しいセッションを開始します。

from database.create_session import Session
session = Session()

さらに読む

<=>の適切な使用法をカバーする非常に興味深いredditスレッドがあります:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_in_init_in_init_in_init_in_init_on_init_in_init_in_init_on_what_to

多数の意見は、<=>ファイルへの違反を避けるために<=>ファイルを非常に薄くする必要があると思われる;明示的は暗黙的<!> quotよりも優れている。哲学。

__init__.py

には2つの主な理由があります
  1. 便宜上:他のユーザーは、パッケージ階層内の関数の正確な位置を知る必要はありません。

    your_package/
      __init__.py
      file1.py
      file2.py
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass
    

    その後、他の人はadd()を呼び出すことができます

    from your_package import add
    

    file1を知らなくても

    from your_package.file1 import add
    
  2. 何かを初期化する場合。たとえば、ロギング(最上位に配置する必要があります):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    

__init__.pyファイルにより、Pythonはそれを含むディレクトリをモジュールとして扱います。

さらに、これはモジュールにロードされる最初のファイルなので、モジュールをロードするたびに実行するコードを実行したり、エクスポートするサブモジュールを指定したりするために使用できます。

Python 3.3以降、インポート可能なPythonパッケージとしてディレクトリを定義するために__init__.pyは不要になりました。

PEP 420:暗黙的な名前空間パッケージ

  

don <!>#8217; tが<=>マーカーファイルを必要とし、自動的に複数のパスセグメントにまたがることができるパッケージディレクトリのネイティブサポート( PEP 420

テストは次のとおりです。

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

references:
https://docs.python.org/3 /whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3のパッケージには__init__.pyは必要ありませんか?

Pythonでは、パッケージの定義は非常に簡単です。 Javaと同様に、階層構造とディレクトリ構造は同じです。ただし、パッケージには__init__.pyが必要です。以下の例で<=>ファイルを説明します:

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

<=>は、存在する限り空でもかまいません。ディレクトリをパッケージと見なす必要があることを示します。もちろん、<=>は適切なコンテンツを設定することもできます。

module_n1に関数を追加する場合

def function_X():
    print "function_X in module_n1"
    return

実行後:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

次に、階層パッケージに従って、module_n1を関数と呼びました。次のようにsubPackage_bで<=>を使用できます。

__all__ = ['module_n2', 'module_n3']

実行後:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1

したがって*インポートを使用して、モジュールパッケージは<=>コンテンツの対象となります。

Pythonは__init__.pyファイルがなくても機能しますが、ファイルを含める必要があります。

パッケージをモジュールとして扱う必要があると指定されているため、パッケージを含めます(空であっても)。

methods.pyファイルを実際に使用する場合もあります:

次のファイル構造があると想像してください:

main_methods 
    |- methods.py

そしてfoo()にはこれが含まれていました:

def foo():
    return 'foo'

main_methodsを使用するには、次のいずれかが必要です。

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

おそらく、import jsonjson内に保持する必要がある(またはしたい)(たとえば、ランタイム/依存関係)が、インポートするのはLib/json/__init__.pyだけである。


<=>の名前を<=>に変更した場合、<=>をインポートするだけで<=>を使用できます:

import main_methods
print(main_methods.foo()) # Prints 'foo'

これは、<=>がパッケージの一部として扱われるため機能します。


一部のPythonパッケージは実際にこれを行います。例は JSON で、実行中の<=>は実際に<=>をインポートしています<=>パッケージから(こちらのパッケージファイル構造を参照):

  

ソースコード: <=>

__init__.pyは、ディレクトリをロード可能なモジュールとして扱います。

コードを読むことを好む人のために、ここに Two-Bit Alchemistのコメントを書いています。

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 

他のpythonファイルのインポートを容易にします。このファイルを、他のpyファイルを含むディレクトリ(たとえばstuff)に配置すると、stuff.otherをインポートするようなことができます。

root\
    stuff\
         other.py

    morestuff\
         another.py

ディレクトリ内でこの__init__.pyがないと、other.pyをインポートできません。Pythonがソースコードの場所を認識せず、パッケージとして認識できないためです。

__init__.pyファイルを使用すると、インポートが簡単になります。パッケージ内にa()が存在する場合、関数b.pyはファイル<=>から次のようにインポートできます。

from b import a

ただし、それなしでは、直接インポートすることはできません。システムパスを修正する必要があります:

import sys
sys.path.insert(0, 'path/to/b.py')

from b import a
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top