質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

5562閲覧

importした外部モジュールのグローバル変数が初期化されるタイミング

dt9672

総合スコア17

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2グッド

0クリップ

投稿2020/04/02 06:03

Pyhton3にて、importした外部モジュールのグローバル変数がいつどのように初期化されるのかご教示いただけますでしょうか。
各種ドキュメントを見ても理解できず実機で試しましたが、実行結果を見ても今一つ腹落ちしない状況です。

当初の仮説

・importしたモジュール内の関数が呼ばれる度に、当該モジュール内でグローバル変数の初期化が行われる

試したコード (1)

Main.py

Python

1import Test 2 3print (Test.test1) 4Test.printtest1() 5Test.printtest1() 6Test.printtest1()

Test.py

Python

1test1 = 5 2 3def printtest1(): 4 global test1 5 test1 += 1 6 print(test1)

予想結果 (1)

5
6
6
6

実際の結果 (1)

5
6
7
8

上記を受けての仮説

・importしたモジュールのグローバル変数の初期化は、import元でimportした時点でのみ行われる

試したコード (2)

Main.py

Python

1import Test 2 3print (Test.test1) 4Test.printtest1() 5Test.printtest1() 6Test.printtest1() 7 8#普通はこんな場所に書きませんがテスト用にあえて 9import Test 10 11print (Test.test1) 12Test.printtest1() 13Test.printtest1() 14Test.printtest1()

Test.py

Python

1#変更なし 2test1 = 5 3 4def printtest1(): 5 global test1 6 test1 += 1 7 print(test1)

予想結果 (2)

5
6
7
8
5
6
7
8

実際の結果 (2)

5
6
7
8
8
9
10
11

結果からの推察

・importしたモジュールのグローバル変数は、当該モジュール内の関数が最初に呼ばれた時のみ1度だけ初期化される
・「当該モジュール」「最初に呼ばれた」はPythonの処理系がいい感じに管理していてユーザーは意識しなくて良い

自分としては明確なルールがわかったとは言い難く、importしたモジュール内のグローバル変数を安心して参照、変更し難いです。
どなたかご教示いただけませんでしょうか。

200269km, LouiS0616👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

追記
まず、質問者様の

・importしたモジュールのグローバル変数の初期化は、import元でimportした時点でのみ行われる

この仮説は正しいものです。importするスクリプトは、import時に一度評価されるだけです。それ以降importしたメソッドを呼んでも、Test.pyのtest1=5の部分が再実行されるわけではないので、値は更新
されません。(もちろんTest.test1=5などと明示的に変更する場合は別です)

(追記ここまで)

Pythonでは同名のモジュールのimportは一度だけしか行われません。2回目のimport時は既にimportされていることを確認して何も行わない仕様になっています。したがって、グローバル変数が更新されていないわけではなく、モジュール全体が更新されていないわけです。

そのため、global変数の値もそのまま残っています。

以下のように、再度読み込みなおしたい場合にはimportlib.reloadを用います。
https://docs.python.org/ja/3/library/importlib.html#importlib.reload

投稿2020/04/02 06:22

編集2020/04/02 06:36
suomo

総合スコア82

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dt9672

2020/04/02 06:30

ご回答ありがとうございます。まとめると、「importしたモジュールのグローバル変数の初期化は、import元でimportが実際に実行された時点でのみ行われる」ということですね。
suomo

2020/04/02 06:33

すみません、不十分な回答でしたね。おっしゃる通りです。 上記を受けての仮説 ・importしたモジュールのグローバル変数の初期化は、import元でimportした時点でのみ行われる これは全くもって正しく、そこにimportは一度しか行われないという挙動が合わさった結果、ご提示の結果が得られています。
dt9672

2020/04/02 06:46

ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問