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

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

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

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

Q&A

3回答

1171閲覧

[Python3]クラスを他クラス(メソッド)内で利用することについて

hirame19168

総合スコア3

Python 3.x

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

0グッド

0クリップ

投稿2019/09/03 10:11

以前した質問と似通っているのですが,ご回答いただけると幸いです.

様々なデータを保持している2つのクラスをある関数に渡して,その中でお互いのデータを用いて計算を行う,というのが今やりたいことです.
簡単に例示したのが以下のコードです.

Python

1# date.py 2class Date_1: 3 # メソッドやら変数やら 4 # 主にデータの保持 5 def __init__(self): 6 self.a = 0 7 self.b = 1 8 9class Date_2: 10 # 上に同じようにデータを保持 11 def __init__(self): 12 self.a = 0 13 self.b = 1

Python

1# main.py 2import date 3 4def calc(date_1, date_2): 5 # Date_1とDate_2のメンバ変数を用いて計算を行う. 6 # 以下の例は適当です. 7 a = date_1.a * date_2.a 8 b = date_1.a * date_2.b 9 c = a + b 10 return c 11 12 13if __name__ == "__main__": 14 date_1 = date.Date_1() 15 date_2 = date.Date_2() 16 17 """ date_1とdata_2に格納するデータを取得する処理 """ 18 19 result = calc(date_1, date_2) 20

このようにインスタンスごとメソッドに渡して処理するというのはよく行われるものなのでしょうか.

何らかの都合でDate_1クラスのメンバ変数self.aself.aaaに変更しようとすると,calc()も書き換える必要がありますし,個人的にはそこを分離したいと考えています.
必要な変数だけを渡すようにすればcalc()とクラスの分離ができるかとおもいましたが,引数が多くなってしまうので,それならばインスタンスごと渡したほうが分かりやすいと思って上記のようにしています.

あとこれを気にするのは変なのかもしれませんが,上記のようにすると,calc()の内容を記述する際にDate_1やDate_2の変数やメソッドに対してコード補完が働かないので少々やりづらいなと感じています.(この程度のコードであればいいのですが,実際にはDateクラスは複数の変数を保持しています.)
calc()内部でインスタンス化すれば解消はするのですが,date_1date_2calc()以外でも利用したいので外でインスタンス化するしかないかなと考えています.

こういう状況ではどうすべきなのか,ご教授お願いいたします.

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

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

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

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

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

guest

回答3

0

私ならこう書くかなぁ。

python

1class Date: 2 def __init__(self, a, b): 3 self.a = a 4 self.b = b 5 6 def __mul__(self, other): 7 return Date(self.a * other.a, self.b * other.b) 8 9 @property 10 def c(self): 11 return self.a + self.b 12 13class Date_1(Date): 14 def __init__(self): 15 super().__init__(0, 1) 16 17class Date_2(Date): 18 def __init__(self): 19 super().__init__(0, 1) 20 21 22date_1 = Date_1() 23date_2 = Date_2() 24result = (date_1 * date_2).c

投稿2019/09/03 11:50

YouheiSakurai

総合スコア6142

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

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

hirame19168

2019/09/09 08:25

ご回答ありがとうございます. result = (date_1 * date_2).c の部分で何をやっているのか分からないので教えていただけないでしょうか.
YouheiSakurai

2019/09/09 09:49

result = date_1.__mul__(date_2).c と同義です。オブジェクト同士の掛け算を__mul__メソッドで定義しています。
hirame19168

2019/09/09 16:47

__mul__で掛け算を定義できるのですね. このような書き方は初めて見たので大変勉強になりました. ありがとうございます.
guest

0

このようにインスタンスごとメソッドに渡して処理するというのはよく行われるものなのでしょうか.

についてお答えすると、まずトップレベルに定義された関数はメソッドではありません。そしてインスタンスを渡すのはよく行われるというか、避けて通れないものです。普通の整数だってintクラスのインスタンスですし。

設計の時点で各クラスと関数を質問文のように使うことを保証するのであれば、そんなに問題があるコードとは思いません。この場合は。aaaaにしようとするのが間違い、みたいな話になります。

ポリシーの話をするなら、まずデータの保持のためにクラスを定義するのが良い方針なのか? 汎用の組み込みの(あとcollectionsの)データ構造とかで済ませられないか? というところから始まると思います。

投稿2019/09/03 12:58

hayataka2049

総合スコア30933

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

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

hirame19168

2019/09/09 08:17

ご回答ありがとうござういます. メソッドと関数の区別がついておりませんでした.メソッドは,クラスが自身のデータを操作するために持っている関数,という認識であっていますでしょうか. この方法自体は間違っていないのですね.ただクラス定義が必要かどうかに関しては,一度考えてみたほうがよさそうですね.
guest

0

まず2つのクラスの関係が分からないので、これらは独立したモノとして定義します。
そして各クラスにはcalcに必要なモノを返す責任を負わせます。
calcは各クラスから必要なモノを引っ張ってきて、それを使って計算をします。
以下、単純な概念コードです。

Python

1class Hoge: 2 def __init__(self): 3 self.a = 1 4 self.b = 2 5 # その他いろいろ 6 7 # calcに必要なモノだけを返す 8 def get_calc_context(self): 9 return self.a, self.b 10 11class Fuga: 12 def __init__(self): 13 self.aa = 3 14 self.bb = 4 15 # その他いろいろ 16 17 # calcに必要なモノだけを返す 18 def get_calc_context(self): 19 return self.aa, self.bb 20 21def calc(h, f): 22 # calcに必要なモノだけを取得する 23 hc1, hc2 = h.get_calc_context() 24 fc1, fc2 = f.get_calc_context() 25 26 # なんらかの計算 27 ret = hc1 * fc1 + hc2 * fc2 28 29 return ret 30 31if __name__ == "__main__": 32 h = Hoge() 33 f = Fuga() 34 35 result = calc(h, f) 36 print(result)

上記であれば各クラスのメンバ変数名が変わる程度ならcalc側の変更は不要ですしcalcに必要なモノが変われば、各クラスのget_calc_contextを変えるだけでよいです。

投稿2019/09/03 12:47

can110

総合スコア38233

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

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

hirame19168

2019/09/09 08:18

ご回答ありがとうございます. setter的なものを用意してあげるということですね.
can110

2019/09/09 09:03

この場合はgetter的なものになります。
hirame19168

2019/09/09 16:45

返す,ですもんね. ご指摘ありがとうございます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問