デコレーターで関数以外を返した場合はどうなるのかを確認します。
結論
- エラーは起きない
- 受け取った関数名で、渡した値が定義される
def decotator(func: Callable):
return 'test'
@decorator
def test_func():
return 1
>>> test_func
'test'
# メソッドの場合も同様
class Test:
@decorator
def test_method(self):
return 1
>>> Test.test_method
'test'
これを利用してcallback
をデコレーターでラップしてオブジェクトを定義する、ということをやってみました。
DjangoのModelForm
のようにCSVを扱える自作nパッケージmodel-csv
で以下のような使い方を実装してみました。
# 今までの使い方
class BookCsv(ModelCsv):
# Column インスタンスを定義していた
title = columns.MethodColumn(header='title')
# callback は別にメソッドで定義していた
# field_<名前> で探している
def field_title(self, *args, **kwargs):
return ...
title
というクラス変数の名前をもとにcallback
メソッドを探していたのですが、
デコレーターでも定義できるようにしました。
# 新しい使い方
class BookCsv(ModelCsv):
# デコレーターの内部で Column インスタンスを作成して返している
# Column オブジェクトの callback に定義した title メソッドを渡している
@columns.as_column(header='title')
def title(self, *args, **kwargs):
return ...
いろいろとできることは増えますが、混乱を招く危険性もあるので注意が必要です。