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

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

ただいまの
回答率

89.65%

Python でclass内にdecoratorを持たせたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 6,043

super_hogehoge

score 23

前提・実現したいこと

Python でclass内にdecoratorを持たせたい

発生している問題・エラーメッセージ

Traceback (most recent call last):
  File "deco2.py", line 1, in <module>
    class MyClass(object):
  File "deco2.py", line 12, in MyClass
    @decorator
TypeError: decorator() takes exactly 2 arguments (1 given)

該当のソースコード

class MyClass(object):
    def __init__(self):
        self.my_var = "my_var" # 追加しました
    # pass

    def decorator(self, func):
        def inner(*args, **kwargs):
            print "pre func"
            print self.my_var # 追加しました
            func(*args, **kwargs)
            print "after_func"
        return inner

    @decorator  #ここでエラーになります
    def print_hoge(self):
        print "hoge"


temp = MyClass()
temp.print_hoge()

試したこと

def decorator(func):
    def inner(*args, **kwargs):
        print "pre func"
        func(*args, **kwargs)
        print "after_func"
    return inner


@decorator
def print_hoge():
    print "hoge"

print_hoge()

>>pre_func
>>hoge
>>after_func

補足情報(言語/FW/ツール等のバージョンなど)

いつも参考にさせていただいております。
非常に簡単な質問かも知れないのですが、実力が足りず解決方法が分からない為教えてください。

【試したこと】の欄のソースでは上手くいくのに、class内に入れた際うまく行きません。

よろしくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

decoratorメソッドのself引数を消すといかがですか。

class MyClass(object):
    def __init__(self):
        pass

    def decorator(func):
        def inner(*args, **kwargs):
            print "pre func"
            func(*args, **kwargs)
            print "after_func"
        return inner

    @decorator
    def print_hoge(self):
        print "hoge"


temp = MyClass()
temp.print_hoge()

self 等にアクセスしたい場合は、以下のようにします。

#coding: utf-8

class MyClass(object):
    def __init__(self):
        self.my_var = "my_var" # 追加しました

    def decorator(func):
        def inner(self, *args, **kwargs):
            print "pre func"
            print self.my_var # 追加しました
            func(self, *args, **kwargs)
            print "after_func"
        return inner

    @decorator
    def print_hoge(self, *args, **kwargs):
        print "hoge"


temp = MyClass()
temp.print_hoge()

selfがなくて良い理由ですが、上のコードは実質以下のコードと同義です。
selfを使うのはあくまでselfが定義しているメソッド内で、今回の例ではdecoratorメソッドは素直に参照できます。

# デコレータをつけないバージョン
    def print_hoge(self, *args, **kwargs):
        print "hoge"
    print_hoge = decorator(print_hoge)
    # print_hoge = self.decorator(print_hoge)  selfをつけるとエラー。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/21 10:47

    ご回答ありがとうございます!!
    ただ、すいません、私の例が悪かったです。確かに教えていただいたコードで出力されますが、self引数を消すと、
    ```python
    class MyClass(object):
    def __init__(self):
    self.my_var = "my_var" # 追加しました
    pass

    def decorator(func):
    def inner(*args, **kwargs):
    print "pre func: "
    print self.my_var # 追加しました
    func(*args, **kwargs)
    print "after_func "
    return inner

    @decorator
    def print_hoge(self):
    print "hoge"


    temp = MyClass()
    temp.print_hoge()
    ```

    のようなclass内部の変数にアクセスできず、selfを付けると@self.decoratorと書いた
    箇所でエラーになってしまうので困っていました。

    例が適切な物ではなくご迷惑をお掛けしました…
    上記問題についても知見をお持ちでご教授いただけると非常に助かります。

    お手数をお掛けしますがよろしくお願い致します。




    キャンセル

  • 2016/10/21 12:20

    ご回答ありがとうございます!
    正直、私の力不足でclass内methodなのにself無くてよいの?等しっくり来ていないところ
    もあるのですが 問題は解決していただけたのでご回答をベストアンサーとさせていただきます。
    迅速に回答していただきとても助かりました。ありがとうございました!

    キャンセル

  • 2016/10/21 15:45

    >selfを使うのはあくまでselfが定義しているメソッド内で、今回の例では
    >decoratorメソッドは素直に参照できます。

    なるほど・・・てっきりclass内の関数は全てselfを引数に持たないといけないのかと
    誤認していました。回答して下さった上にこちらの疑問にフォローしていただき
    非常にすっきり問題を解決することができました。 ありがとうございました!

    キャンセル

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

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる