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

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

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

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

Python

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

Q&A

解決済

2回答

26101閲覧

pythonのファイル間をまたいだクラス変数の共有について

JapaneseRobot

総合スコア13

Python 3.x

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

Python

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

0グッド

2クリップ

投稿2016/12/28 05:26

###前提・実現したいこと
python3.x系でクラス変数について以下のようなテストプログラムを書きました。
目的はクラス変数を用いてモジュール間でまたいで参照できる共通の変数を持たせたかったからです。
サンプルコードでいうところのモジュールtest1, test2でクラス変数A.aの共有がしたかったです。

###発生している問題・エラーメッセージ
test1, test2でクラス変数A.aが共有されずに、Aのそれぞれ別のオブジェクトがtest1, test2で作成されているように見えます。

問題1:
クラスAの初期化処理がtest2のなかでAをimportする段階でも呼び出されています。クラスAのA.aを共有したいので初期化処理を再度呼び出されるのは動作として希望するものではありません。

問題2:
A.aに行った変更処理がそれぞれのtest1, test2で相互に適用されていないです。クラス変数を共有したいのでこれは動作として希望するものではありません。

以上の問題はクラス変数の使い方が誤っているのか、認識が誤っているのかどちらでしょうか。
ファイルモジュールをまたいでクラス変数を共有する方法があれば御教授願いたくおもいます。

###該当のソースコード

python

1------test1.py------ 2import test2 3 4class A: 5 a = 10 6 print("print a from A initialization") 7 print(a) 8 9 def print_a(self): 10 print("print a from A") 11 print(A.a) 12 13def main(): 14 B1 = test2.B() 15 A.a = 100 16 print("check1") 17 B1.print_a() 18 print("check2") 19 A1 = A() 20 A1.print_a() 21 print("check3") 22 23 24if __name__ == "__main__": 25 main() 26 27 28 29------test2.py------ 30class B: 31 def print_a(self): 32 from test1 import A 33 print("print a from B") 34 print(A.a) 35 A.a = A.a + 10

###test1.pyの実行結果
print a from A initialization
10
check1
print a from A initialization
10
print a from B
10
check2
print a from A
100
check3

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

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

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

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

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

guest

回答2

0

ベストアンサー

原因は、「直接実行された test1.pytest1 モジュールではない」というところにあります。

main.pyを以下の内容で作って、 python main.py で実行すれば、想定通りの挙動になります。

Python

1from test1 import A 2import test2 3 4def main(): 5 B1 = test2.B() 6 A.a = 100 7 print("check1") 8 B1.print_a() 9 print("check2") 10 A1 = A() 11 A1.print_a() 12 print("check3") 13 14 15if __name__ == "__main__": 16 main()

直接実行されたスクリプト(test1.py)は、モジュール名が __main__ になります。これは、 __name__ 変数に格納されています。このため、test2.pyがimportして参照している test1.A__main__.A は別物です。

なお、クラス変数を外から書き換えるのはあまり推奨できないので、アーキテクチャを見直した方がよいと思います。

投稿2016/12/28 08:02

shimizukawa

総合スコア1847

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

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

JapaneseRobot

2016/12/28 08:13

回答ありがとうございます。 モジュール名が直接実行されると__main__になることは知りませんでした。 その後のクラス変数を外から書き換えるのは推奨できないと合わせて、とてもためになりました。 サンプルコードを変更して実行したところ確かに想定の動作を致しました。 モジュールを分けることとアーキテクチャの変更の両方を行いたいと思います。 たいへんありがとうございました。
guest

0

モジュールtest1, test2でクラス変数A.aの共有がしたかった

java等で言う「static変数」のことを言ってるようですね。

このへん↓の記事が参考になりますかね。
Pythonにおけるクラスの静的メンバについて - 試験運用中なLinux備忘録

投稿2016/12/28 05:59

tkturbo

総合スコア5572

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

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

JapaneseRobot

2016/12/28 06:37

回答ありがとうございます。 まさしくおっしゃる通り、C++などでいうところの静的メンバー変数が作りたかったわけです。 リンク先を拝見させていただきましたが、ファイルをまたぐように用いる例はそちらにはないようです。 今回はpythonでのクラス変数([クラス名].[メンバ変数名]で定義された変数)が静的メンバー変数にあたると思い、その点に関してはいただいたリンク先と同じ思想です。しかしながら私が提示したサンプルコードの用にtest1, test2とまたいで使ったときにクラスオブジェクト自体が複数生成されてしまい(初期化処理が2回行われている)、共有がされていないようにみえたため質問させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問