45

モジュールのデータに内部からアクセスしようとしています__main__.py

構造は次のとおりです。

mymod/
    __init__.py
    __main__.py

ここで、次のように変数を公開すると、次の__init__.pyようになります。

__all__ = ['foo']
foo = {'bar': 'baz'}

fooからアクセスするにはどうすればよい__main__.pyですか?

4

6 に答える 6

23

パッケージがすでににあるか、にsys.pathを含むディレクトリを追加するmymodsys.path、スイッチ__main__.pyを使用する必要があります。-m

パスに追加mymodするには、次のようになります(in __main__.py):

import sys
import os
path = os.path.dirname(sys.modules[__name__].__file__)
path = os.path.join(path, '..')
sys.path.insert(0, path)
from myprog import function_you_referenced_from_init_file

-mスイッチの使用方法は次のとおりです。

python -m mymod

詳細については、この回答を参照してください。

于 2010-08-05T11:11:18.417 に答える
4

この種のことで私が最も遭遇する問題は、機能をテストするためのスクリプトとしてファイルを実行したいことが多いということですが__init__.py、パッケージをロードするときにこれらを実行するべきではありません。との間のさまざまな実行パスには、便利な回避策がありpython <package>/__init__.pyますpython -m <package>

  • $ python -m <module>を実行し<package>/__main__.pyます。__init__.pyロードされていません。
  • $ python <package>/__init__.py__init__.py通常のスクリプトのようにスクリプトを実行するだけです。

問題

からのものを使用__init__.pyするif __name__ == '__main__': ...句が必要な場合。常にインタプリタのパスからインポートされるため、インポートできません。( …絶対パスインポートハックに頼らない限り、他の多くの混乱を引き起こす可能性があります)。__main__.py__main__.py__main__.pyc


ソリューション解決策 :)

モジュールの__main__:に2つのスクリプトファイルを使用します。

<package>/
         __init__.py
         __main__.py
         main.py

# __init__.py

# ...
# some code, including module methods and __all__ definitions

__all__ = ['foo', 'bar']
bar = {'key': 'value'}
def foo():
    return bar
# ...
if __name__ == '__main__':
    from main import main
    main.main()

# __main__.py

# some code...such as:
import sys
if (len(sys.argv) > 1 and sys.argv[1].lower() == 'option1'):
    from main import main()
    main('option1')
elif (len(sys.argv) > 1 and sys.argv[1].lower() == 'option2'):
    from main import main()
    main('option2')
else:
    # do something else?
    print 'invalid option. please use "python -m <package> option1|option2"'

# main.py

def main(opt = None):
    if opt == 'option1':
        from __init__ import foo
        print foo()
    elif opt == 'option2':
        from __init__ import bar
        print bar.keys()
    elif opt is None:
        print 'called from __init__'

から実行している場合、インポートmain.pyはおそらく理想的ではありません。すでに__init__.pyロードされているにもかかわらず、別のモジュールのローカルスコープにリロードしているため__init__.pyですが、明示的なロードでは循環ロードを回避する必要があります。__init__モジュール全体をに再度ロードすると、main.pyとしてロードされない__main__ため、循環ロードに関する限り安全である必要があります。

于 2012-07-19T18:41:26.863 に答える
2

パッケージ__init__モジュールはパッケージ自体のメンバーのように機能するため、オブジェクトは次の場所から直接インポートされます。mymod

from mymod import foo

または

from . import foo

簡潔にしたい場合は、相対的なインポートについて読んでください。いつものようにmymod/__main__.py、たとえば、Pythonがmymodパッケージとして検出されないようにするために、モジュールを呼び出さないようにする必要があります。を調べてみてくださいdistutils

于 2010-08-05T02:20:57.170 に答える
1

でモジュールを実行するとpython -m mymod、コードイン__main__.pyはモジュールをに追加しなくてもモジュールの残りの部分からインポートできるようになりますsys.path

于 2012-05-10T19:57:17.970 に答える
0

最初の答えは便利であることがわかりました(つまり、ハッキングsys.path)がpathlib、Python 3.4に追加すると、次のコードがはるかに単純でPythonicであることがわかりました。

import sys
from pathlib import Path

# You don't need to .insert(), just append
sys.path.append(str(Path(__file__).parent.parent))
于 2021-07-29T22:57:33.293 に答える
-2

モジュールディレクトリの構造は次のとおりです。

py/
   __init__.py
   __main__.py

__init__。py

#!/usr/bin/python3
#
# __init__.py
#

__all__ = ['foo']
foo = {'bar': 'baz'}
info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)

__main__。py

#!/usr/bin/python3
#
# __main__.py
#

info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)
from . import info as pyinfo
print({"pyinfo: ": pyinfo})

-mフラグを使用してモジュールをスクリプトとして実行します

$ python -m py

# the printout from the 'print(info)' command in __init__.py
{'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}
# the printout from the 'print(info)' command in __main__.py
{'name': '__main__', 'locals': ['__builtins__', '__name__', '__file__', '__loader__', '__doc__', '__package__'], 'package': 'py'}
# the printout from the 'print(pyinfo)' command in __main__.py
{'pyinfo: ': {'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}}
于 2012-03-19T06:06:05.167 に答える