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

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

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

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

Q&A

解決済

1回答

930閲覧

【python3】コンストラクタはデコレータにできますか?

shirai

総合スコア1290

Python 3.x

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

1グッド

0クリップ

投稿2019/07/09 11:40

編集2019/07/09 15:51

実現したいこと

以下のようなプログラムは実行できるでしょうか。
親クラスと子クラスは分けたいです。
試しに実行してみたところ@super().__init__でsyantax errorが出ました。

python

1class Parent(object): 2 def __init__(func): 3 def inner(mojiretsu): 4 print('start') 5 func(mojiretsu) 6 print('end') 7 return inner 8 9class Child1(Parent): 10 @super().__init__ 11 def child1(mojiretsu): 12 print('1: ' + mojiretsu) 13 14class Child2(Parent): 15 @super().__init__ 16 def child2(mojiretsu): 17 print('2: ' + mojiretsu) 18 19c1 = Child1() 20c2 = Child2() 21 22c1.child1('aiueo') 23c2.child2('12345') 24 25# 想定される出力 26# start 27# 1: aiueo 28# end 29# start 30# 2: 12345 31# end
YouheiSakurai👍を押しています

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

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

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

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

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

quickquip

2019/07/09 13:28

このコードでは、素朴な感想として普通のデコレータでいいじゃないかとしか思えないので、もう少し普通のデコレータでは実現できなさそうな例を挙げなければ質問に意味がないと思います。(「親クラスと子クラスは分けたいです」のあたり?) c2 = Child1() は誤記でしょう。修正するといいかと。
shirai

2019/07/09 15:55

分かりました。デコレータを使うべきか見直してみます。ありがとうございます。 プログラムのミス修正しました。
guest

回答1

0

ベストアンサー

そもそも__init__メソッドはオブジェクトを返せません。()

Python

1class Parent(object): 2 def __init__(func): 3 def inner(mojiretsu): 4 print('start') 5 func(mojiretsu) 6 print('end') 7 return inner 8 9p = Parent() # TypeError: __init__() should return None, not 'function'

註: 厳密にはNoneだけ返せる。

コンストラクタはデコレータにできますか?

コンストラクタというのが__init__メソッドを指すなら、有用には扱えません。
デコレータとは高階関数を噛ませた再代入に過ぎないからです。

文法上は問題無いと思いますが、あまりに実用とかけ離れます。

追記

あ、こういうのなら可能ですよ。__init__は内部的に呼ばれます。

Python

1class Parent(object): 2 def __init__(self, func): 3 self.func = func 4 5 def __call__(self, mojiretsu): 6 print('start') 7 self.func(mojiretsu) 8 print('end') 9 10class Child1(Parent): 11 def __init__(self): 12 pass 13 14 @Parent 15 def child1(mojiretsu): 16 print('1: ' + mojiretsu) 17 18class Child2(Parent): 19 def __init__(self): 20 pass 21 22 @Parent 23 def child2(mojiretsu): 24 print('2: ' + mojiretsu) 25 26c1 = Child1() 27c2 = Child2() 28 29c1.child1('aiueo') 30c2.child2('12345')

しかしこれも使い勝手は良くなさそうです。

投稿2019/07/09 11:46

編集2019/07/09 11:53
LouiS0616

総合スコア35660

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

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

shirai

2019/07/09 15:58

なるほどそうなんですね。 __call__も知らなかったので勉強になりました。 ありがとうございます。 確かに素直な書き方をした方が良さそうですね。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問