6

NumPyのように機能するPythonモジュールを作成したいと思います。メソッドは、モジュールソースからのツリーの葉にあるサブモジュールだけではありません。直接呼び出すことができる多くのメソッドを含むルートモジュールがあり、サブモジュールもあります。問題は、ルートメソッドをどこかで定義する必要があることです。私はディレクトリ構造を持つことを考えていました:

module/
  __init__.py
  core.py
  stuff1.py
  submodule/
    __init__.py
    stuff2.py
    stuff3.py

ここで必要なのは、「core」内のすべてを「module」名前空間にインポートすることです。あたかもそれがmodule.pyファイルであり、core.pyの内容がこのmodule.py内にあるかのようになります。問題は、モジュールがファイルではなくディレクトリであるということです。モジュールのルートに配置する必要があるこれらのメソッドをどのように定義すればよいですか?

「fromcoreimport *」をinit.pyに入れてみましたが、うまくいきませんでした。(編集:実際にはそうです。)

「module.py」ファイルとモジュールディレクトリ内にコアメソッドを含める必要がありますか?それがうまくいくかどうかはわかりませんが、かなり厄介に見えます。

4

2 に答える 2

5

私があなたが望んでいると思うのは、これができることです:

# some_other_script.py

import module
# Do things using routines defined in module.core

Pythonに要求するimport moduleと、(非常に基本的な意味で)module/__init__.py実行され、moduleオブジェクトが作成されて名前空間にインポートされます。このオブジェクト(これも非常に基本的に)には、__init__.py実行時に発生した名前の定義などが含まれます。これらには、からアクセスできますmodule.something

ここで、セットアップが次のようになっている場合:

# module/__init__.py

from module.core import Clazz
c = Clazz()
print c # Note: demo only! Module-level side-effects are usually a bad idea!

をインポートするmoduleと、次のようなprintステートメントが表示されます。

<module.core.Clazz object at 0x00BBAA90>

素晴らしい。しかし、次にアクセスしようとするとc、次のようになりますNameError

# some_other_script.py
import module # prints "<module.core.Clazz object at 0x00BBAA90>"
print c # NameError (c is not defined)

これは、インポートしていないためですc。インポートしましたmodule。代わりに、エントリポイントスクリプトが次のようになっている場合:

# some_other_script.py
import module # prints "<module.core.Clazz object at 0x00BBAA90>"
print module.c  # Access c *within module*

すべてが正常に実行されます。これは、および/またはで正常機能しますが、ワイルドインポートをいじり始めたときにスクリプトで何が起こっているのかが明確でないという理由だけで、私(およびPEP8)はこれに反対することをお勧めします。明確にするために:from core import *from module import *

# module/core.py

def core_func():
    return 1


# module/__init__.py

from core import *
def mod_func():
    return 2

上記は実際にはかなり問題ありませんが、パッケージの外部から触れる理由がなくなったことを示すためにcore「プライベート」(名前を)に変更することもできます。_core

# some_other_script.py

from module import *

print core_func() # Prints 1
print mod_func() # Prints 2
于 2013-03-11T23:59:10.720 に答える
3

リストに関する情報を確認してください__all__。エクスポートする名前を定義できます。

そのようにタグ付けすると、サブモジュールから何をプルするかを決定する関数を設定できます。

@property
all(self):
    #Whatever introspective code you may want for your modules
    __all__ += submodule.__all__

モジュールスペースでひどいシバン全体が必要な場合は、次の方法があります。

$ ipython
In [1]: from foomod import *

In [2]: printbar()
Out[2]: 'Imported from a foreign land'

In [3]: ^D
Do you really want to exit ([y]/n)?
$ ls foomod/
__init__.py __init__.pyc    core.py         core.pyc        submodule
$ grep . foomod/*.py 
foomod/__init__.py:from foomod.core import *
foomod/core.py:def printbar():
foomod/core.py:     return "Imported from a foreign land"

...そして私たちが__init__.py空にした場合:

$ echo > foomod/__init__.py
$ ipython

In [1]: from foomod import *

In [2]: printbar()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-ba5b6693441e> in <module>()
----> 1 printbar()

NameError: name 'printbar' is not defined
于 2013-03-11T20:21:38.610 に答える