Python3: 属性名のみの括弧無しでメソッドを実行する

2020-04-16

#Python3 クラス デコレータ

あるクラスの設計で、何かの計算された値を返したいとき、引数なしのメソッドを実装することが有ると思います。
その場合、値の取得は次のような形になります。

しかし、返される値が何かの属性値、例えばそのオブジェクトの長さのようなものであれば、括弧なしで x.foo として取得したくなるのが人情というものです。

@property デコレータ

Python 3 には、そのような動作を手軽な記述で可能にする @property デコレータがあります。
次の例で、@property デコレータの基本的な利用法を示します。

なお、@wrapper 構文のデコレータは、メソッド(関数)やクラスの直前の行に付与することで、その定義内容を自動的に書き換える為の仕組みです。

文字数を返す属性値の実装

Python 3 の文字列クラス str には、JavaScript 等のように length プロパティは無く、組み込み関数 len(s) で文字列 s の長さを取得します。
そこで、文字数を s.length でも取得できるように実装してみましょう。

クラス str を継承し、length プロパティを実装した新たな文字列クラス String を作りました。
length メソッド内の定義方法は通常のメソッドと同様ですが、@property の付与により s.length で戻り値が取得できるようになっています。

メソッドが読み出し専用属性になる

上記の例の length は読み出し専用属性に変化しており、値を書き込んだり、s.length() として実行することは出来ません。

従って、単に読み出し専用属性を作りたい時にも @property は便利と言えます。
また、読み出し専用を含むデータ用クラスを作りたい時は、@dataclass デコレータも便利です。

※ Python 3.7 で動作確認しました。

参考サイト

QooQ