luigi で パラメータで与えられた日付をtimedelta を使って増減させたい
背景
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