简体   繁体   English

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

[英]SyntaxError using *args and **kwargs in an __init__ in Python

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 . 我正在尝试定义一个RecurringInterval类, dateutil.rrule使用从dateutil.rrule到composition的rrule类,此外还具有属性period ,默认情况下为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 : 但是,我得到一个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). (从https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists尚不明确)。

I tried bringing period=None forward, like so: 我试图使period=None前进,如下所示:

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 : 但这会引发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? 如何以预期的方式初始化RecurringInterval

它应该是:

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

Updated answer 更新的答案

Following Python, default keyword arguments after variable length positional arguments , the following works in Python 3: Python之后,默认关键字参数在变长位置参数之后 ,以下代码在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 : 在这篇Github文章之后 ,我找到了使用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 . 这样,将period作为关键字参数给出,将其分配给self.period ,其默认值为None ,而其余​​的argskwargs用于初始化RecurringIntervalself.rrule

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM