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

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

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

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

Q&A

解決済

1回答

1786閲覧

2つのプログラム間のメソッドを複数直接行き行きするとエラーが起こる

tomo1998

総合スコア34

Python 3.x

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

0グッド

0クリップ

投稿2018/12/13 21:26

前提・実現したいこと

本プログラム側とモジュール側のメソッドがお互いのメソッドを呼び合う
といったプログラムを作成中に不可解なエラーに遭遇しました

本プログラムとモジュールがあり、お互いがお互いをインポートした状態で
本プログラム側からモジュールのメソッド、(仮の呼び名として2_1)を呼び出す→呼び出されたモジュールのメソッド(2_1)が本プログラム側のメソッド(仮の呼び名として1_1)を呼び出す→本プログラム側のメソッド(1_1)がモジュールのメソッド(2_2)を呼び出すとAttributeErrorになる
といった現象が起きました

該当のソースコード

分かりやすいようにサンプルプログラムを作ってみました

本プログラム側 プログラム名:test1

Python3

1import test2 as t2 2class App001(object): 3 def test1_1(self): 4 self.Test2=t2.App002() 5 self.Test2.test2_0() 6 self.Test2.test2_1() 7 8 def test1_2(self,text001): 9 print(text001) 10 self.Test2.test2_2() 11 12if __name__ == '__main__': 13 App=App001() 14 App.test1_1() 15

モジュール側 プログラム名:test2

python3

1import test1 as t1 2class App002(object): 3 def __init__(self): 4 self.text001="TextA" 5 self.text002="TextB" 6 7 def test2_0(self): 8 print("Text from module") 9 10 def test2_1(self): 11 self.Test1=t1.App001() 12 self.Test1.test1_2(self.text001) 13 14 def test2_2(self): 15 print(self.text002) 16 17if __name__ == '__main__': 18 App=App002() 19 App.test2_1() 20 21

発生している問題・エラーメッセージ

エラーメッセージ

self.Test2.test2_2() AttributeError: 'App001' object has no attribute 'Test2'

試したこと

お互いがお互いをインポートしているので、相手側のメソッドは何の問題もなく呼び出せれるはずなのですが、プログラムがAttributeErrorエラーを起こすのはやっぱりメソッドを直接何度も生き行きしているからなのでしょうか?
この問題を解決するにはどうすればいいでしょうか

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

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

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

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

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

guest

回答1

0

ベストアンサー

App001クラス側で、test1_1が実行されないとself.Test2が作られません。そしてtest1_2ではself.Test2を使おうとしています。

App002クラス側のtest2_1はインスタンスを生成して、いきなりtest1_2を呼ぶので、そのようなエラーになります。

投稿2018/12/13 21:59

hayataka2049

総合スコア30933

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

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

tomo1998

2018/12/13 22:09

なるほど・・・本プログラム側で def __init__ を追加して、こちら側でself.Test2=t2.App002()  を定義したらエラーが起こらなくなりました。 しかし、何故インスタンスを作成していきなりtest1_2を呼ぶとエラーが起こるのでしょうか?そこらへんがよくわからないです( ̄▽ ̄;) いきなりtest1_2を呼び出したとしても、test1_2側でself.Test2が定義されるのですが、何故ダメなんです?定義が終わる前にtest2_2を呼び出すから・・・とか?
hayataka2049

2018/12/13 22:23 編集

def test2_1(self): の以下の行を確認してもらえるとわかりますが、 self.Test1=t1.App001() # App001のインスタンス化 self.Test1.test1_2(self.text001) # 新しく生成したインスタンスに対してtest1_2の呼び出し となり、self.Test1=t1.App001() の行で生成されたインスタンスに対してはtest1_1が呼ばれません。
hayataka2049

2018/12/13 22:24

>いきなりtest1_2を呼び出したとしても、test1_2側でself.Test2が定義されるのですが、何故ダメなんです?定義が終わる前にtest2_2を呼び出すから・・・とか? test1_2側で定義・・・されてませんねぇ def test1_2(self,text001): print(text001) self.Test2.test2_2()
tomo1998

2018/12/13 22:34

ふむむ・・・ あ、確かに if __name__ == '__main__': App=App001() App.test1_1() と本プログラム側に書いてあるので、問題ないと思ったのですが、モジュールが本プログラム側読み込んだ場合はtest1_1は呼ばれないからなんですね
hayataka2049

2018/12/13 22:35

いえ、そうではなくて、そこでApp=App001()したときのAppと self.Test1=t1.App001() # App001のインスタンス化 のときのself.Test1はそもそも別のインスタンスです
tomo1998

2018/12/13 22:42

え、そうなんですか? 確かに別々だと考えれば何故エラーが起こったのかもっと納得できる・・・ うぅむ。。。てっきり同じものかと思っていました。プログラミングって難しいなぁ(-_-;)
hayataka2049

2018/12/13 23:48

同じインスタンスにしたければ self.Test1=t1.App とかで参照できませんか
tomo1998

2018/12/14 05:12

self.Test1=t1.App001() の代わりにself.Test1=t1.Appを書くってことですか? そしたら以下のようなエラーが・・・ self.Test2.test2_0() TypeError: test2_0() missing 1 required positional argument: 'self'
tomo1998

2018/12/14 05:14

試しに引数のある()以外の()を削除してみたのですが、そしたらエラーは起こらなくなったのですがその代わりに実行しても何も表示されず・・・
hayataka2049

2018/12/14 05:19

コードを書き換えたからでは? 質問文の状況からそこだけ変えたら、そのエラーにはなりませんでした。ただ、エラーは出ますね。 AttributeError: module 'test1' has no attribute 'App' 循環importだから評価のタイミングがシビアで、グローバル変数のAppが見えないのか。上の私のコメントは間違いでした。 今更だけど、色々とややこしいので循環importを使わないで書ければそうした方が良いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問