クラスがインポートできない!
- 評価
- クリップ 2
- VIEW 550
概要
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
class Dictionary:
def __init__(self):
""" 辞書オブジェクトの作成
"""
self.__load_history()
def __load_history(self):
"""ファイルを読み込み、世界史の辞書オブジェクトを作成
"""
with open('data1/world_history.txt', 'r', encoding='utf_8'
) as file:
lines = file.readlines()
new_lines = []
for line in lines:
line = line.rstrip('\n')
if line != '':
new_lines.append(line)
separate = []
for line in new_lines:
sp = line.split('\t')
separate.append(sp)
self.__history = dict(separate)
def save(self):
"""self.historyの内容を加工してファイルに書き込む
"""
write_lines = []
for key, val in self.history.items():
write_lines.append(key + '\t' + val + '\n')
with open('data1/world_history.txt', 'w', encoding='utf_8') as f:
f.writelines(write_lines)
def get_history(self):
return self.__history
def set_history(self, history):
self.__history = history
history = property(get_history, set_history)
if __name__ == '__main__':
dictionary = Dictionary()
print(dictionary.history)
dictionary.save()
responder.py
from dictionary import *
class Responder:
def __init__(self, dictionary):
self.__dictionary = dictionary
def response(self, input, what):
return ''
# __historyのゲッター
def get_dictionary(self):
return self.__dictionary
# __historyのセッター
def set_dictionary(self, history):
self.__history = history
dictionary = property(get_dictionary, set_dictionary)
class HistoryResponder(Responder):
def response(self, input, what):
if input in self.dictionary.history:
return '「' + self.dictionary.history[input] + '」です。'
else:
return '理解できませんでした。答えを入力して下さい。'
class StudyHistoryResponder(Responder):
def response(self, input, what):
self.dictionary.history[what] = input
return '記憶しました'
if __name__ == '__main__':
dictionary = Dictionary()
# responder = HistoryResponder(dictionary)
history_resp = HistoryResponder(dictionary)
ans = history_resp.response('世界四大文明', '')
print(ans)
study_resp = StudyHistoryResponder(dictionary)
ans = study_resp.response('ディアドコイ', 'アレクサンドロス大王の後継者')
print(dictionary.history)
ray.py
from responder import *
from dictionary import *
class Ray:
def __init__(self):
self.__dictionary = Dictionary()
self.__res_history = HistoryResponder(self.__dictionary)
self.__study_history = StudyHistoryResponder(self.__dictionary)
def dialogue(self, input, subject, study, what):
if subject == 0 and study == 0:
self.responder = self.res_history
elif subject == 0 and study == 1:
self.responder = self.study_history
return self.responder.response(input, what)
def save(self):
""" Dictionaryのsave()を呼ぶ中継メソッド
"""
self.dictionary.save()
@property
def dictionary(self):
return self.__dictionary
@property
def res_history(self):
return self.__res_history
@property
def study_history(self):
return self.__study_history
if __name__ == '__main__':
ray = Ray()
ans = ray.dialogue('世界四大文明', 0, 0, '')
print(ans)
ans = ray.dialogue('アレクサンドロス大王の後継者', 0, 0, '')
print(ans)
ans = ray.dialogue('ディアドコイ', 0, 1, 'アレクサンドロス大王の継続者')
print(ans)
print(ray.dictionary.history)
ray.save()
world_history.txt
古代ギリシアの植民市 ビサンティウム、ネアポリス、マッサリア
古代ギリシアの三大悲劇詩人 アイスキュロス、ソフォクレス、エウリピデス
シェイクスピアの四大悲劇 オセロ、マクベス、リア王、ハムレット
ローマ帝王の五賢帝 ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス
カースト制度の身分 バラモン、クシャトリヤ、ヴァイシャ、シュードラ
ロシアの歴代大統領 エリッツン、プーチン、メドヴェージェフ
世界四大文明 エジプト文明、メソポタミア文明、インダス文明、黄河文明
三国志の三国 魏、呉、蜀
ルネサンス期の三大発明 火薬、羅針盤、活版印刷
三国時代の三国 高句麗、百済、新羅
アレクサンドロス大王の継続者 ディアドコイ
Ray1.py
from rayl.ray import *
import tkinter
import tkinter.messagebox
import re
tk = tkinter
entry = None
response_area = None
action = None
ray = Ray()
study = 0
what = ''
def talk():
global study, what
value = entry.get()
subject = action.get()
print('Formsubject==', subject)
print('Formstudy==', study)
if not value:
response_area.configure(text='ご用件をお申し付け下さい')
elif subject == 0 and study == 0:
response = ray.dialogue(value, subject, study, what)
response_area.configure(text=response)
m = re.match('理解できませんでした。', response)
print('m===', m)
if m:
study = 1
what = value
entry.delete(0, tk.END)
elif subject == 0 and study == 1:
response = ray.dialogue(value, subject, study, what)
response_area.configure(text=response)
study = 0
what = ''
entry.delete(0, tk.END)
def run():
global entry, response_area, action
root = tk.Tk()
root.title("Super Bot --Ray1-- : ")
# ウィンドウサイズ
root.geometry("880x460")
# フォント
font = ('Helevetica', 14)
def calloback():
if tkinter.messagebox.askyesno('Quit?', '辞書を更新してもよろしいですか'):
ray.save()
root.destroy()
else:
root.destroy()
root.protocol('WM_DELETE_WINDOW', calloback)
# メニューバーの作成
menubar = tk.Menu(root)
filemenu = tk.Menu(menubar, tearoff=0)
# ファイルメニュー
filemenu.add_command(label="閉じる", command=calloback)
menubar.add_cascade(label="ファイル", menu=filemenu)
# 編集メニュー
optionmenue = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="科目", menu=optionmenue)
optionmenue.add_radiobutton(label='世界史', variable=action, value=0)
optionmenue.add_radiobutton(label='英語(単語)', variable=action, value=1)
root.config(menu=menubar)
# 上の画像
# 画像サイズ(横x縦)
c = tk.Canvas(root, width=870, height=200, relief=tk.RIDGE, bd=2)
c.pack()
c.place(x=1, y=0)
nw = tk.PhotoImage(file='img1.gif')
# 画像の位置
c.create_image(0, 0, anchor=tk.NW)
# 背景
response_area = tk.Label(root, width=86, height=10, bg='White', font=font, relief=tk.RIDGE, bd=2)
response_area.place(x=6, y=210)
# フレームの作成
frame = tk.Frame(root, bd=4, relief=tk.RIDGE)
# 入力ボックスの作成
entry = tk.Entry(frame, width=70, font=font)
entry.pack(side=tk.LEFT)
entry.focus_set()
button = tk.Button(frame, width=15, text='入力')
button.pack(side=tk.LEFT)
frame.place(x=30, y=420)
root.mainloop()
if __name__ == '__main__':
run()
dictionaly.py実行結果
{'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ'}
Process finished with exit code 0
responder.py実行結果
「エジプト文明、メソポタミア文明、インダス文明、黄河文明」です。
{'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ', 'アレクサンドロス大王の後継者': 'ディアドコイ'}
Process finished with exit code 0
ray.py実行結果
理解できませんでした。答えを入力して下さい。
記憶しました
{'古代ギリシアの植民市': 'ビサンティウム、ネアポリス、マッサリア', '古代ギリシアの三大悲劇詩人': 'アイスキュロス、ソフォクレス、エウリピデス', 'シェイクスピアの四大悲劇': 'オセロ、マクベス、リア王、ハムレット', 'ローマ帝王の五賢帝': 'ネルヴァ、トラヤヌス、ハドリアヌス、アントニヌス・ピウス、マルクス・アウレリウス・アントニヌス', 'カースト制度の身分': 'バラモン、クシャトリヤ、ヴァイシャ、シュードラ', 'ロシアの歴代大統領': 'エリッツン、プーチン、メドヴェージェフ', '世界四大文明': 'エジプト文明、メソポタミア文明、インダス文明、黄河文明', '三国志の三国': '魏、呉、蜀', 'ルネサンス期の三大発明': '火薬、羅針盤、活版印刷', '三国時代の三国': '高句麗、百済、新羅', 'アレクサンドロス大王の継続者': 'ディアドコイ'}
Process finished with exit code 0
コード
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
importに失敗している、というのは質問文の状況から行った推測であって、実行した際にエラーなどが出るわけではないのですね?
pythonではimportの失敗はエラー(例外)になりますから、エラーが出なければ何らかの形でimportには成功しています。原因は他の部分にあるのだと思います。
GUIのRay1.pyのコードに定義されているtalk関数についてですが、このプログラムの中核になる処理のように見えるのに、コード内で呼び出される仕組みがないようです。意図通り動作しないのはそのせいではないでしょうか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
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といった似たような宣言があるのですが、
質問主の事象だと「*なんて曖昧な表現せずにちゃんと細かく指定しろ」みたいな怒られ方をすることがあるので
似たような次第だと思いました…
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/10/26 10:18
2019/10/27 19:12
button = tk.Button(frame, width=15, text='入力')
のcommandとかに指定すべきものなのでしょう。
単にそれだけでちゃんと動くという訳でもなさそうなので、しっかり確認していただくのがいいと思いますが、とりあえずそれで。
2019/10/28 07:04
2019/10/28 17:08