ソフトな忘却力(112) PythonのDecoratorで関数を修飾する練習

Joseph Halfmoon

「サイエンティフィックPythonのための」IDE、Spyder上にてScientific Python Lecturesの実習中。前回はGeneratorとの「双方向通信」。今回はDecoratorです。時々デコレータ使ったカッコいいコードを拝見することがあるのですが、自分じゃ出来る気がしません。メンドクセーとこ改善。

※「 ソフトな忘却力」投稿順 Index はこちら

Scientific Python Lectures様のコースは例題だけでなく、エクササイズなども充実、それを全部順番に解いていったら必ずや立派な人になれるだろ~と思います。でも老い先短い年寄には量が多過ぎて多分死ぬまでに終わりません。適当な練習でお茶を濁してます。今回は「7.2 Decorators」の「7.2.1 Replacing or tweaking the original object」です。

Decorator

御存じのとおり、デコレータはこんな感じっす(いい加減な説明。)

    1. 普通に定義された関数(やクラス)の前に@マークに続けてデコレータ名を書く
    2. すると定義されたオブジェクトを単一の引数としてデコレータが呼び出される
    3. デコレータの中で元のオブジェクトがやってないことを、あれやこれやテコ入れ処理するオブジェクトとして、これを返り値として返す
    4. オブジェクトとして返って来た関数(やクラス)を使うと、「あれやこれや」パワーアップしたような効果がでる

なんだか@マーク「お名前」とするだけで、機能が追加されたみたいで嬉しいデス。例えば、今回の練習のfunctionAは、2つの引数 x と aの掛け算の結果を返すだけの関数ですが、デコレータを使うとアーラ不思議、キーワード引数に対応したり、引数が不在のときにデフォルト値を返すなどの「あれやこれや」も可能となります。src

上記の結果はこんな感じ。result

練習ソース

デコレータ定義の練習のソースが以下に。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Aug 5 2025

@author: jhalfmoon
Decorator definition training
"""

def chkDecorator(function):
    def wrapper(*args, **kwargs):
        x = 1.0
        a = 1.0
        if len(args) > 0:
            x = float(args[0])
        if 'a' in kwargs:
            a = float(kwargs['a'])
        print("Decorator x:{0} a:{1}".format(x, a))
        result = function(x, a) + 2
        return result
    return wrapper

@chkDecorator
def functionA(x, a):
    print("FUNC x:{0} a:{1}".format(x, a))
    return a * x

def main():
    print("functionA=", functionA(2.0, a=3.0))
    print("functionA=", functionA())

if __name__ == '__main__':
    main()

まあ、こんくらいならばまあ書けないこともないっと。大丈夫か?

ソフトな忘却力(111) PythonのGeneratorとsend()で双方向通信? へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です