Pythonのimportの仕様を確かめる

お仕事中に話題になったもので。

mod1.py

def func1():
    print('mod1.func1 called')

print('mod1 imported')

main.py

from mod1 import func1 
from mod1 import func1 
func1()

結果

mod1 imported
mod1.func1 called

ですね。importを複数回行っても、最初の時にpycacheが作られて2回目はそれが使われますね。これはいいんですよ。

次に、以下のmod2.pyを足して、

mod2.py

def func1():
    print('mod2.func1 called')

print('mod2 imported')

main.py

from mod1 import func1 
from mod2 import func1
from mod1 import func1 
func1()

結果

mod1 imported
mod2 imported
mod1.func1 called

これが今回試したかったケースなんですが、まあ予想通りでしたね。読み込み直す時でもpycacheが使われる。まあ、そりゃそうですね。

そしてさらに、以下。

mod3.py

def func1():
    print('mod3.func1 called')

def func2():
    print('mod3.func2 called')

print('mod3 imported')

main.py

from mod3 import func1
from mod1 import func1 
from mod3 import func2 

func2()

結果

mod3 imported
mod1 imported
mod3.func2 called

まあ、別に代わり映えのしない結果になりました。面白くなくてすいません。つまり、from〜importで一部だけをimportしたつもりでも、ちゃんと全部丸ごと読み込まれていて、from〜importに書かなかった要素もpycacheから持ってくるしくみになっているよ、ということでした。

実際には、これがif文の中に書いてあったせいで、HTTPリクエストのたびに叩かれることになり、無駄に動的なimportがたくさん走るんじゃないの、それって大丈夫なの、みたいな話の流れでした。特に、そういう意味では問題はなさそうですね。ただまあ、必要もないのに関数の中でimportせんでくれよ。それでなくともわしゃ忙しいんじゃ。それではまた〜