LoginSignup
1
0

More than 5 years have passed since last update.

Pythonの下位モジュールの扱い

Posted at

聞かれたときに間違えて答えて恥しかったのでメモしておく。
事の発端はscipy.specialが参照できなかったという話。
つまりこういうことだった。

import scipy as sci

sci.special # AttributeError

import scipy.special
scipy.special # Not error

上のパターンでエラーが起きるとは思ってなかったので面喰らった。
調べてみた。

下位モジュール

Pythonではあるモジュールの内側に別のモジュールをネストさせられる。
いままで上位のモジュールをインポートしたら下位のモジュールも参照できるのが当然だと思っていたけどどうも違うらしい。
テストするために簡単なモジュールを作成した。

テスト

こんな感じの構成になった。
使ったのはpython3.6.1。

test.py
test1/
    __init__.py
    test2/
        __init__.py
test.py
import test1

print(dir(test1))

# callable
test1.func_in_test1()

# not callable
try:
    test1.test2.func_in_test2()
except AttributeError as e:
    print("Error!")

import test1.test2
print(dir(test1))

# callable here
test1.test2.func_in_test2()
test1/__init__.py
def func_in_test1():
    print('test1')
    return
test2/__init__.py
def func_in_test2():
    print('test2')
    return

test.pyを動かしてテストしてみた、出力は以下のようになった。

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'func_in_test1']
test1
Error!
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'func_in_test1', 'test2']
test2

下位モジュールの関数を見れていないし、そもそも下位モジュール自体が名前空間(で合っているんだろうか?)に含まれていない。
下位のモジュールを使う場合には明示的にインポートしないといけないらしい。
おそらく、外部には公開しない内部向けのモジュールのためにそうなっているのだと思う。
ちなみに、test1/__init.py__内でインポートしたモジュールは問題なく参照できる。

知らんかった。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0