Reputation: 57791
I'm trying to define a class RecurringInterval
which uses the rrule
class from dateutil.rrule
through composition, and in addition has the attribute period
which by default is None
. I've tried to initialize it in this way:
class RecurringInterval(object):
def __init__(self, *args, period=None, **kwargs):
self.period = period
self.rrule = dateutil.rrule.rrule(*args, **kwargs)
recurring_interval = RecurringInterval(dateutil.rrule.DAILY, count=1)
However, I get a SyntaxError
:
File "/home/kurt/dev/scratch/Furion_scheduler/recurring_interval.py", line 7
def __init__(self, *args, period=None, **kwargs):
^
SyntaxError: invalid syntax
As I understand it, positional arguments should come before keyword arguments, so this is how I would expect the syntax to be; how would I correct it? (From https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists this is not yet clear to me).
I tried bringing period=None
forward, like so:
class RecurringInterval(object):
def __init__(self, period=None, *args, **kwargs):
self.period = period
self.rrule = dateutil.rrule.rrule(*args, **kwargs)
but this gives rise to a TypeError
:
Traceback (most recent call last):
File "/home/kurt/dev/scratch/Furion_scheduler/recurring_interval.py", line 9, in <module>
recurring_interval = RecurringInterval(dateutil.rrule.DAILY, count=1)
File "/home/kurt/dev/scratch/Furion_scheduler/recurring_interval.py", line 7, in __init__
self.rrule = dateutil.rrule.rrule(*args, **kwargs)
TypeError: __init__() takes at least 2 arguments (2 given)
How can I initialize the RecurringInterval
in the intended fashion?
Upvotes: 1
Views: 3544
Reputation: 57791
Updated answer
Following Python, default keyword arguments after variable length positional arguments, the following works in Python 3:
class RecurringInterval(object):
def __init__(self, *args, duration=datetime.timedelta(seconds=0), **kwargs): # Initializing in this way only works in Python 3
self.duration = duration
self.rrule = dateutil.rrule.rrule(*args, **kwargs)
Old answer
Following this Github article, I found a solution using kwargs.pop
:
class RecurringInterval(object):
def __init__(self, *args, **kwargs):
self.period = kwargs.pop('period', None)
self.rrule = dateutil.rrule.rrule(*args, **kwargs)
recurring_interval = RecurringInterval(dateutil.rrule.DAILY, count=1, period=datetime.timedelta(days=2))
This way, period
is given as a keyword argument, it is assigned to self.period
, the default value of which is None
, while the remaining args
and kwargs
are used to initialize the RecurringInterval
's self.rrule
.
Upvotes: 1
Reputation: 600059
It should be:
def __init__(self, period=None, *args, **kwargs):
Upvotes: 4