背景
luigi にて、パラメータで与えられた日付に対して、固定日分前(例えば一週間など)を求めたい。
from datetime import timedelta import luigi class MyTask(luigi.Task): date = luigi.DateParameter() start_date = date - timedelta(days=7)
と書くと、次のようなエラー。
unsupported operand type(s) for -: 'DateParameter' and 'datetime.timedelta'
確かに、date はDateParameterなので、エラーの通りなのだが。
での、回答者のコメントでは、 “DateParameter returns a value that is a python date. ” といってるので、半分信じてしまった。
ちなみにこのQAは役立たない。なぜならデフォルト値の計算をしたいわけではないから。
クラス変数とインスタンス変数の違い
関数の中の、self.date はクラス変数と思っていたが、間違いだ。これはインスタンス変数だ。
厄介なことに、 self.date の表記は python 的にはクラス変数でもインスタンス変数にもなるらしい。
インスタンス変数として「初期化」すれば、クラス変数は隠蔽され以後インスタンス変数として扱われる。
ただ参照するだけならば、クラス変数として扱われる。
結局、self.date がインスタンス変数ということは、親のクラスのインスタンス初期化の処理などで、クラス変数の設定通りの動作が行われ、self.date というインスタンス変数に値がセットされたのだろう。
解決
from datetime import timedelta import luigi class MyTask(luigi.Task): date = luigi.DateParameter() def requires(self): start_date = self.date - timedelta(days=7)
もし、固定の日でなく、パラメータで与えたいのであれば、TimeDeltaParameter を使おう。
http://luigi.readthedocs.io/en/stable/api/luigi.parameter.html#luigi.parameter.TimeDeltaParameter