Python: 使用 **kwargs 定义类

7
尝试实例化以下类时,出现以下错误:
"TypeError: __init__() takes exactly 2 arguments (3 given)"

您知道会出现什么问题吗?这是类的定义:

class db_create_table():
        '''
            doc here
        '''
        def __init__(self,TableName, **kwargs ):
            self.TableName = TableName
            for k,v in kwargs.iteritems():
                setattr(self, k, k)


schema =  {"id" : { "type":"Integer", "primary":"primary_key=True", "unique":"unique = True"},
           "col1" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = True"},
           "col2" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "col3" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "col4" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "CreatedOn" :  { "type":"DateTime", "primary":"", "unique":"unique = False"},
           "UpdatedOn" :  { "type":"DateTime", "primary":"primary_key=False", "unique":"unique = False"},
                            }


db_create_table('Table1', schema)
4个回答

6
为了通过schema并将其解压到**kwargs中,您必须使用**schema
db_create_table('Table1', **schema)
说明:单个星号(*args)将序列解包成参数列表,而双星号(**kwargs)将类似字典的对象解包成关键字参数列表。

不带星号时,给定的对象将直接按原样传递,没有任何解包操作。

参见如何在Python中使用*args和**kwargs


2
进一步解释这个答案,你也可以写成(简化版):db_create_table('Table1', id=1, col1=2, col2=3, CreatedOn='2017-09') - rocksteady

3
该函数中的kwargs参数捕获关键字参数;您正在传递一个未解包的单个对象。
您需要使用**将其解包,或在函数定义中添加*args。例如,查看函数如何解释参数:
def func(*args, **kwargs):
    print args
    print kwargs

func(arg)
func(*arg)
func(*arg, keyword='key')

输出:

(('one', 'two'),)  -- passed as arg, single element
{}
('one', 'two')  -- passed as *arg - object is unpacked
{}
('one', 'two')
{'keyword': 'key'}  -- keyword arg looks like that

当您在调用函数时使用 **kwargs 传递关键字参数时,您可以使用 *args 传递位置参数。

0
你传递了两个参数args,但只捕获了kwargs
schema作为一个位置参数被传递,它会被*args捕获;如果你想让它被**kwargs捕获,你必须将其作为关键字参数传递:

db_create_table('Table1', schema=schema)

该函数没有名为"schema"的参数。也许你想说的是"kwargs=schema"?即使是这样,我认为你还需要双星号吧? - Basya
它没有名为“schema”的参数。但是它确实有**kwargs,并且任何传递的命名参数都会进入那里。 - deceze
@deceze 实际上,当传递 schema=schema 并打印类变量时: test = db_create_table('Table1', schema = schema)print vars(test)您会发现 schema 被传递为字符串,而不是具有字典键的形式。 - Pelican
2
@user 不,你会得到一个名为 schema 的属性,其值为 dict。我只能猜测你真正想要做什么,因为你没有说清楚。@glglgl 可能是正确的方向。 - deceze

0

db_create_table( 'Table1', id = { "type":"整数", "primary":"primary_key=True", "unique":"unique = True"}, col1 = { "type":"字符串()", "primary":"primary_key=False", "unique":"unique = True"}, col2 = { "type":"字符串()", "primary":"primary_key=False", "unique":"unique = False"}, col3 = { "type":"字符串()", "primary":"primary_key=False", "unique":"unique = False"}, col4 = { "type":"字符串()", "primary":"primary_key=False", "unique":"unique = False"}, CreatedOn = { "type":"日期时间", "primary":"", "unique":"unique = False"}, UpdatedOn = { "type":"日期时间", "primary":"primary_key=False", "unique":"unique = False"} )


你的回答可以通过添加更多支持信息来改进。请[编辑]以添加更多详细信息,比如引用或文献,这样其他人就可以确认你的答案是否正确。你可以在 帮助中心找到有关如何撰写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接