0

私はこのファイル構造を持っています(ドットは私の作業ディレクトリです):

.
+-- testpack
     +-- __init__.py
     +-- testmod.py

testmodステートメントを使用してモジュールをロードすると、次のimport中で宣言されている関数を呼び出すことができます。

>>> import testpack.testmod
>>> testpack.testmod.testfun()
hello

しかし、関数を使用して同じことをしようとすると、うまくいき__import__()ません:

>>> __import__("testpack.testmod").testfun()

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    __import__("testpack.testmod").testfun()
AttributeError: 'module' object has no attribute 'testfun'

実際、testpackモジュールの代わりにパッケージを返しますtestmod:

>>> __import__("testpack.testmod").testmod.testfun()
hello

どうして?

4

1 に答える 1

4

この動作はドキュメントに記載されています:

name変数がpackage.moduleの形式の場合、通常、名前で指定されたモジュールではなく、最上位のパッケージ(最初のドットまでの名前)が返されます。ただし、空でないfromlist引数を指定すると、nameで指定されたモジュールが返されます。

..。

ステートメントimportspam.hamは、次の呼び出しになります。

spam = __import__('spam.ham', globals(), locals(), [], -1)

__import__()これはimportステートメントによって名前にバインドされるオブジェクトであるため、ここでトップレベルモジュールを返す方法に注意してください。

上部の警告にも注意してください。

これは、とは異なり、日常のPythonプログラミングでは必要とされない高度な関数ですimportlib.import_module()

そして後で:

モジュール(場合によってはパッケージ内)を名前でインポートするだけの場合は、を使用しますimportlib.import_module()

したがって、ここでの解決策はを使用することimportlib.import_module()です。

Pythonの名前の両側に二重下線が付いていることは、手元のオブジェクトがほとんどの場合直接使用されることを意図していないことを意味していることに注意してください。len(x)一般的にoverx.__len__()またはvars(x)/ dir(x)overを使用する必要があるのと同じようにx.__dict__。なぜそれを使用する必要があるのか​​わからない限り、それは一般的に何かが間違っている兆候です。

于 2013-03-04T18:03:37.593 に答える