在Python中的__init__中使用* args和** kwargs的SyntaxError

时间:2016-11-23 16:33:42

标签: python

我试图定义一个类RecurringInterval,它使用rrule中的dateutil.rrule类到合成,另外还有period属性,默认情况下是None。我试图以这种方式初始化它:

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)

但是,我得到SyntaxError

  File "/home/kurt/dev/scratch/Furion_scheduler/recurring_interval.py", line 7
    def __init__(self, *args, period=None, **kwargs):
                                   ^
SyntaxError: invalid syntax

据我了解,位置参数应该出现在关键字参数之前,所以这就是我期望语法的方式;我该如何纠正呢? (来自https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists这对我来说还不清楚。)

我尝试将period=None转发,如此:

class RecurringInterval(object):
    def __init__(self, period=None, *args, **kwargs):
        self.period = period
        self.rrule = dateutil.rrule.rrule(*args, **kwargs)

但这会产生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)

如何以预期的方式初始化RecurringInterval

2 个答案:

答案 0 :(得分:4)

应该是:

def __init__(self, period=None, *args, **kwargs):

答案 1 :(得分:1)

更新回答

关注Python, default keyword arguments after variable length positional arguments,以下内容适用于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)

旧答案

Github article之后,我找到了使用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))

这样,period作为关键字参数提供,它被分配给self.period,其默认值为None,而剩余的args和{ {1}}用于初始化kwargs的{​​{1}}。