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

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

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

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

Q&A

解決済

2回答

2055閲覧

クラスがインポートできない!

Ponde_ling

総合スコア8

Python

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

0グッド

2クリップ

投稿2019/10/24 13:32

編集2019/10/28 08:01

概要

GUIの実行画面に入力したものに対しての返答の文字が出力されない状態で困っています。おそらくメインクラスに他のクラスをインポート出来ていないためだと考えています。今回作成したコードは、GUIの(Ray1.py)、メインクラス(ray.py)、辞書クラス(dictionary.py)と応答クラス(responder.py)であり、応答クラス(responder.py)だけがインポートできない状態で困っています。まだ初心者なので優しく教えてください(>_<)

補足

ray.pyの from responder import * が開発ツール(PyCharm)で薄く表示されるのと、 self.__res_history = HistoryResponder(self.__dictionary) 、
self.__study_history = StudyHistoryResponder(self.__dictionary) 
の部分に赤い波線(エラー?)が出ることや、実行画面で返答がないことから、インポート出来ていないと考えました。実行してもエラー表示は出ません。

コード

dictionary.py

Python

1class Dictionary: 2 3 def __init__(self): 4 """ 辞書オブジェクトの作成 5 """ 6 7 self.__load_history() 8 9 def __load_history(self): 10 """ファイルを読み込み、世界史の辞書オブジェクトを作成 11 """ 12 with open('data1/world_history.txt', 'r', encoding='utf_8' 13 ) as file: 14 lines = file.readlines() 15 16 new_lines = [] 17 18 for line in lines: 19 line = line.rstrip('\n') 20 if line != '': 21 new_lines.append(line) 22 separate = [] 23 for line in new_lines: 24 sp = line.split('\t') 25 separate.append(sp) 26 self.__history = dict(separate) 27 28 def save(self): 29 """self.historyの内容を加工してファイルに書き込む 30 """ 31 write_lines = [] 32 33 for key, val in self.history.items(): 34 write_lines.append(key + '\t' + val + '\n') 35 with open('data1/world_history.txt', 'w', encoding='utf_8') as f: 36 f.writelines(write_lines) 37 38 def get_history(self): 39 return self.__history 40 41 def set_history(self, history): 42 self.__history = history 43 44 history = property(get_history, set_history) 45 46 47if __name__ == '__main__': 48 dictionary = Dictionary() 49 print(dictionary.history) 50 dictionary.save() 51 52

responder.py

Python

1from dictionary import * 2 3 4class Responder: 5 def __init__(self, dictionary): 6 self.__dictionary = dictionary 7 8 def response(self, input, what): 9 return '' 10 11 # __historyのゲッター 12 def get_dictionary(self): 13 return self.__dictionary 14 15 #  __historyのセッター 16 def set_dictionary(self, history): 17 self.__history = history 18 19 dictionary = property(get_dictionary, set_dictionary) 20 21 22class HistoryResponder(Responder): 23 def response(self, input, what): 24 if input in self.dictionary.history: 25 return '「' + self.dictionary.history[input] + '」です。' 26 else: 27 return '理解できませんでした。答えを入力して下さい。' 28 29 30class StudyHistoryResponder(Responder): 31 def response(self, input, what): 32 self.dictionary.history[what] = input 33 return '記憶しました' 34 35 36if __name__ == '__main__': 37 dictionary = Dictionary() 38 # responder = HistoryResponder(dictionary) 39 history_resp = HistoryResponder(dictionary) 40 ans = history_resp.response('世界四大文明', '') 41 print(ans) 42 43 study_resp = StudyHistoryResponder(dictionary) 44 ans = study_resp.response('ディアドコイ', 'アレクサンドロス大王の後継者') 45 print(dictionary.history) 46

ray.py

Python

1from responder import * 2from dictionary import * 3 4 5class Ray: 6 def __init__(self): 7 8 self.__dictionary = Dictionary() 9 10 self.__res_history = HistoryResponder(self.__dictionary) 11 12 self.__study_history = StudyHistoryResponder(self.__dictionary) 13 14 def dialogue(self, input, subject, study, what): 15 if subject == 0 and study == 0: 16 self.responder = self.res_history 17 18 elif subject == 0 and study == 1: 19 self.responder = self.study_history 20 21 return self.responder.response(input, what) 22 23 def save(self): 24 """ Dictionaryのsave()を呼ぶ中継メソッド 25 """ 26 self.dictionary.save() 27 28 @property 29 def dictionary(self): 30 return self.__dictionary 31 32 @property 33 def res_history(self): 34 return self.__res_history 35 36 @property 37 def study_history(self): 38 return self.__study_history 39 40 41if __name__ == '__main__': 42 ray = Ray() 43 ans = ray.dialogue('世界四大文明', 0, 0, '') 44 print(ans) 45 46 ans = ray.dialogue('アレクサンドロス大王の後継者', 0, 0, '') 47 print(ans) 48 49 ans = ray.dialogue('ディアドコイ', 0, 1, 'アレクサンドロス大王の継続者') 50 print(ans) 51 print(ray.dictionary.history) 52 53 ray.save() 54 55

world_history.txt

txt

1古代ギリシアの植民市 ビサンティウム、ネアポリス、マッサリア 2古代ギリシアの三大悲劇詩人 アイスキュロス、ソフォクレス、エウリピデス 3シェイクスピアの四大悲劇 オセロ、マクベス、リア王、ハムレット 4ローマ帝王の五賢帝 ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス 5カースト制度の身分 バラモン、クシャトリヤ、ヴァイシャ、シュードラ 6ロシアの歴代大統領 エリッツン、プーチン、メドヴェージェフ 7世界四大文明 エジプト文明、メソポタミア文明、インダス文明、黄河文明 8三国志の三国 魏、呉、蜀 9ルネサンス期の三大発明 火薬、羅針盤、活版印刷 10三国時代の三国 高句麗、百済、新羅 11アレクサンドロス大王の継続者 ディアドコイ 12

Ray1.py

Python

1 2from rayl.ray import * 3import tkinter 4import tkinter.messagebox 5import re 6 7tk = tkinter 8 9entry = None 10response_area = None 11action = None 12ray = Ray() 13study = 0 14what = '' 15 16 17def talk(): 18 global study, what 19 20 value = entry.get() 21 subject = action.get() 22 print('Formsubject==', subject) 23 print('Formstudy==', study) 24 if not value: 25 response_area.configure(text='ご用件をお申し付け下さい') 26 elif subject == 0 and study == 0: 27 response = ray.dialogue(value, subject, study, what) 28 response_area.configure(text=response) 29 m = re.match('理解できませんでした。', response) 30 print('m===', m) 31 if m: 32 study = 1 33 what = value 34 entry.delete(0, tk.END) 35 elif subject == 0 and study == 1: 36 response = ray.dialogue(value, subject, study, what) 37 response_area.configure(text=response) 38 study = 0 39 what = '' 40 entry.delete(0, tk.END) 41 42 43def run(): 44 global entry, response_area, action 45 46 47root = tk.Tk() 48root.title("Super Bot --Ray1-- : ") 49# ウィンドウサイズ 50root.geometry("880x460") 51# フォント 52font = ('Helevetica', 14) 53 54 55def calloback(): 56 if tkinter.messagebox.askyesno('Quit?', '辞書を更新してもよろしいですか'): 57 ray.save() 58 root.destroy() 59 else: 60 root.destroy() 61 62 63root.protocol('WM_DELETE_WINDOW', calloback) 64 65# メニューバーの作成 66menubar = tk.Menu(root) 67filemenu = tk.Menu(menubar, tearoff=0) 68 69# ファイルメニュー 70filemenu.add_command(label="閉じる", command=calloback) 71menubar.add_cascade(label="ファイル", menu=filemenu) 72 73# 編集メニュー 74optionmenue = tk.Menu(menubar, tearoff=0) 75menubar.add_cascade(label="科目", menu=optionmenue) 76optionmenue.add_radiobutton(label='世界史', variable=action, value=0) 77optionmenue.add_radiobutton(label='英語(単語)', variable=action, value=1) 78root.config(menu=menubar) 79 80# 上の画像 81# 画像サイズ(横x縦) 82c = tk.Canvas(root, width=870, height=200, relief=tk.RIDGE, bd=2) 83c.pack() 84c.place(x=1, y=0) 85nw = tk.PhotoImage(file='img1.gif') 86# 画像の位置 87c.create_image(0, 0, anchor=tk.NW) 88 89# 背景 90response_area = tk.Label(root, width=86, height=10, bg='White', font=font, relief=tk.RIDGE, bd=2) 91response_area.place(x=6, y=210) 92 93# フレームの作成 94frame = tk.Frame(root, bd=4, relief=tk.RIDGE) 95 96# 入力ボックスの作成 97entry = tk.Entry(frame, width=70, font=font) 98entry.pack(side=tk.LEFT) 99entry.focus_set() 100 101button = tk.Button(frame, width=15, text='入力') 102button.pack(side=tk.LEFT) 103 104frame.place(x=30, y=420) 105 106root.mainloop() 107 108if __name__ == '__main__': 109 run() 110

dictionaly.py実行結果

{'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ'} Process finished with exit code 0

responder.py実行結果

「エジプト文明、メソポタミア文明、インダス文明、黄河文明」です。 {'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ', 'アレクサンドロス大王の後継者': 'ディアドコイ'} Process finished with exit code 0

ray.py実行結果

理解できませんでした。答えを入力して下さい。 記憶しました {'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ'} Process finished with exit code 0 コード

各コード、画像、テキストの保存場所
各コード、画像、テキストの保存場所
イメージ説明
イメージ説明

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

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

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

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

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

guest

回答2

0

ベストアンサー

importに失敗している、というのは質問文の状況から行った推測であって、実行した際にエラーなどが出るわけではないのですね?

pythonではimportの失敗はエラー(例外)になりますから、エラーが出なければ何らかの形でimportには成功しています。原因は他の部分にあるのだと思います。


GUIのRay1.pyのコードに定義されているtalk関数についてですが、このプログラムの中核になる処理のように見えるのに、コード内で呼び出される仕組みがないようです。意図通り動作しないのはそのせいではないでしょうか。

投稿2019/10/25 03:09

編集2019/10/25 03:11
hayataka2049

総合スコア30933

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

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

Ponde_ling

2019/10/26 01:18

ご回答ありがとうございます。コードの方確認してみます
hayataka2049

2019/10/27 10:12

コードをすべて理解した訳ではありませんが、雰囲気からするとたぶんtalkは button = tk.Button(frame, width=15, text='入力') のcommandとかに指定すべきものなのでしょう。 単にそれだけでちゃんと動くという訳でもなさそうなので、しっかり確認していただくのがいいと思いますが、とりあえずそれで。
Ponde_ling

2019/10/27 22:04

ありがとうございます。試してみます。
Ponde_ling

2019/10/28 08:08

出力した際の表示の画像を添付しました。ウィンドの上部に画像img1.gifが出力されていないのと、入力エリアに未入力の場合「ご用件をお申し付け下さい」と出力してほしいのですが出力されていません。
guest

0

知識がなく、適当な回答になるので、こちらで…

Pythonには学が無いので、あくまで記載されてる情報から、
「もしかしたら」程度で答えます…あまり期待しないでください…

>辞書クラス(dictionary.py)と応答クラス(responder.py)であり、応答クラス(responder.py)だけがインポートできない状態

この発言が事実であれば、「辞書クラス」と「応答クラス」の違いから見てみました。

●辞書クラス

class Dictionary

しかない

●応答クラス

class Responder:

の他にも

class HistoryResponder(Responder):
class StudyHistoryResponder(Responder):

がある。

from responder import * が開発ツール(PyCharm)で薄く表示

>self.res_history = HistoryResponder(self.dictionary) 、
>self.study_history = StudyHistoryResponder(self.dictionary) 
>の部分に赤い波線(エラー?)が出ることや

から、ray.pyが

「responder import *」がなんて使ってねーよ! と言ってる のと
「HistoryResponder」と「StudyHistoryResponder」が見つからねーよ!と言ってるように見受けられます…

●想定される解決策

responder import * を

from responder import HistoryResponder
from responder import StudyHistoryResponder

のような、

「responder」に宣言されたクラスを個別に読み込む

ようなinport宣言というのは出来ないものなのでしょうか…。

(上記記述だと間違いなくエラーがでると思いますが、「responder 」に対しての「HistoryResponder
」や「StudyHistoryResponder」のimport指定のやり方はあると思われます…)

少なくともC#でusingといった似たような宣言があるのですが、
質問主の事象だと「*なんて曖昧な表現せずにちゃんと細かく指定しろ」みたいな怒られ方をすることがあるので
似たような次第だと思いました…

投稿2019/10/24 14:21

編集2019/10/24 14:24
hermit19901127

総合スコア368

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

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

Ponde_ling

2019/10/25 02:45

丁寧なご回答ありがとうございます。検討させて頂きます。
hayataka2049

2019/10/27 10:05

>hermit19901127さん from responder import HistoryResponder from responder import StudyHistoryResponder はまさにその通りの記述で良いので、「上記記述だと間違いなくエラーがでると思いますが」は間違いですね。修正されてはいかがでしょうか。 *を使ったimportはPEP8などでも推奨されていません(https://pep8-ja.readthedocs.io/ja/latest/#import)。多くのlintはそれ自体に警告を出しますし、静的解析ではこれによってimportされる名前は存在しないとして扱われるのが普通だと思います。 ただし、実行時にちゃんと名前解決できれば(実行ができるかどうかという観点だけで見れば)問題はありません。その場合は、 from responder import * と from responder import HistoryResponder from responder import StudyHistoryResponder に大きな違いはありません。 (つまりresponderモジュール配下にHistoryResponderとStudyHistoryResponderが実際に存在していればワイルドカード・インポートでもうまくいく。他の名前で名前空間が汚れる副作用はありますが)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問