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

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

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

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

Q&A

解決済

1回答

1703閲覧

pythonでDictionaryというクラスを継承してUnmoというクラスを実装したい!

oka12

総合スコア8

Python 3.x

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

0グッド

0クリップ

投稿2018/08/20 14:46

編集2018/08/20 15:27

前提・実現したいこと

pythonのプログラムでDictionaryというクラスから継承してUnmoというクラスを実行したいです!

Unmoというクラスを実装中に以下のエラーメッセージが発生しました。

発生している箇所・エラーメッセージ

File "C:\Users\聡一朗\repos\unmo\unmo.py", line 24, in __init__ 'random': RandomResponder('Random', self._dictionary), TypeError: __init__() takes 2 positional arguments but 3 were given

該当のソースコード

unmo.py

from responder import WhatResponder, RandomResponder, PatternResponder from dictionary import Dictionary from random import choice class Unmo: """人工無脳コアクラス。 プロパティ: name -- 人工無脳コアの名前 responder_name -- 現在の応答クラスの名前 """ def __init__(self, name): """文字列を受け取り、コアインスタンスの名前に設定する。 Responder(What, Random, Pattern)インスタンスを作成し、保持する。 Dictionaryインスタンスを作成し、保持する。 """ self._dictionary = Dictionary() self._responders = { 'what': WhatResponder('What', self._dictionary), 'random': RandomResponder('Random', self._dictionary), 'pattern': PatternResponder('Pattern', self._dictionary), } self._name = name self._responder = self._responders['pattern'] def dialogue(self, text): """ユーザーからの入力を受け取り、Responderに処理させた結果を返す。 呼び出されるたびにランダムでResponderを切り替える。""" chosen_key = choice(list(self._responders.keys())) self._responder = self._responders[chosen_key] return self._responder.response(text) @property def name(self): """人工無脳インスタンスの名前""" return self._name @property def responder_name(self): """保持しているResponderの名前""" return self._responder.name

dictionary,py

class Dictionary: """思考エンジンの辞書クラス。 クラス変数: DICT_RANDOM -- ランダム辞書のファイル名 DICT_PATTERN -- パターン辞書のファイル名 プロパティ: random -- ランダム辞書 pattern -- パターン辞書 """ DICT_RANDOM = 'dics_random.txt' DICT_PATTERN = 'dics_pattern.txt' def __init__(self): """ファイルから辞書の読み込みを行う。""" with open(Dictionary.DICT_RANDOM, encoding='utf-8') as f: self._random = [x for x in f.read().splitlines() if x] self._pattern = [] with open(Dictionary.DICT_PATTERN, encoding='utf-8-sig') as f: self._pattern = [Dictionary.make_pattern(l) for l in f.read().splitlines() if l] @staticmethod def make_pattern(line): """文字列lineを半角スペースで分割し、{'pattern': [0], 'phrases': [1]}の形式で返す。""" pattern, phrases = line.split(" ") if pattern and phrases: return {'pattern': pattern, 'phrases': phrases.split('|')} @property def random(self): """ランダム辞書""" return self._random @property def pattern(self): """パターン辞書""" return self._pattern

responder.py

import re from random import choice class Responder: """AIの応答を制御する思考エンジンの基底クラス。 継承して使わなければならない。 メソッド: response(str) -- ユーザーの入力strを受け取り、思考結果を返す プロパティ: name -- Responderオブジェクトの名前 """ def __init__(self, name, dictionary): """文字列を受け取り、自身のnameに設定する。 辞書dictionaryを受け取り、自身のdictionaryに保持する。""" self._name = name self._dictionary = dictionary def response(self, *args): """文字列を受け取り、思考した結果を返す。""" pass @property def name(self): """思考エンジンの名前""" return self._name class WhatResponder(Responder): """AIの応答を制御する思考エンジンクラス。 入力に対して疑問形で聞き返す。""" def response(self, text): """文字列textを受け取り、'{text}ってなに?'という形式で返す。""" return '{}ってなに?'.format(text) class RandomResponder(Responder): """AIの応答を制御する思考エンジンクラス。 登録された文字列からランダムなものを返す。 """ def __init__(self, name): """文字列を受け取り、オブジェクトの名前に設定する。 'dics_random.txt'ファイルから応答文字列のリストを読み込む。""" super().__init__(name) self.responses = [] with open('dics_random.txt', mode='r', encoding='utf-8') as f: self._responses = [x for x in f.read().splitlines() if x] def response(self, _): """ユーザーからの入力は受け取るが、使用せずにランダムな応答を返す。""" return choice() @property def name(self): """思考エンジンの名前""" return self._name class PatternResponder(Responder): """AIの応答を制御する思考エンジンクラス。 登録されたパターンに反応し、関連する応答を返す。 """ def response(self, text): """ユーザーの入力に合致するパターンがあれば、関連するフレーズを返す。""" for ptn in self.dictionary.pattern: matcher = re.match(ptn['pattern'], text) if matcher: chosen_response = choice(ptn['phrases']) return chosen_response.replace('%match%', matcher[0]) return choice(self._dictionary.random)

試したこと

同じエラーを探して参考しようとしたのですが(https://teratail.com/questions/139457)、この事例とは異なり引数の数が明らかに違うわけではないのでうまくいきません。もしかしたらエラーの箇所の付近の構文

self._responders = { 'what': WhatResponder('What', self._dictionary), 'random': RandomResponder('Random', self._dictionary), 'pattern': PatternResponder('Pattern', self._dictionary), }

の構文内の引数が関係しているように思われるですがいかがでしょうか?

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

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

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

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

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

guest

回答1

0

ベストアンサー

そもそも提示されているコードはUnmoがDictionaryを継承するようになっていませんが。

エラーの出ている箇所はUnmoやDictionaryの__init__とは関係ありません。よく確認すると、

File "C:\Users\聡一朗\repos\unmo\unmo.py", line 24, in __init__
'random': RandomResponder('Random', self._dictionary),

TypeError: init() takes 2 positional arguments but 3 were given

RandomResponerの__init__は2つの引数しか取らないのに、3つ渡されていますというエラーです。うち1つはselfなので、実際に渡せる引数は1つです。

どうしてself._dictionaryを渡そうと思ったのでしょうか?

投稿2018/08/20 14:52

編集2018/08/20 15:06
hayataka2049

総合スコア30933

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

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

oka12

2018/08/20 15:27 編集

Responderの__init__は新しい方を使っているのでそこは問題ではなさそうですね。一応、Responderクラスのコードも追記しておきますね。
hayataka2049

2018/08/20 15:37

RandomResponderの実装を直さないと駄目ですね
hayataka2049

2018/08/20 15:42 編集

RandomResponderに独自の__init__があるので親クラスの__init__を上書きしているというのが直接のエラー原因です 他にもresponseの実装がおかしかったり、nameが親クラスと重複定義になっていたり、直すべき点は色々あるようです 記事の「今回のソースはこちら」を見てどうなっているか確認してみてください
oka12

2018/08/20 16:24 編集

「今回のソースはこちら」の通りにしたらTypeErrorは解決しました。ありがとうございました。でも「今回のソースはこちら」の通りにしたのにPatternResponderクラスでRandomな回答を一、二回繰り返した後新たなエラーが出てうまく実行はできませんでしたが、今回の質問で示したエラーは解決したので解決済みにしようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問