传递关键字参数

时间:2009-06-19 14:44:34

标签: python

我有一个需要“通过”特定关键字参数的类函数:

def createOrOpenTable(self, tableName, schema, asType=Table):
    if self.tableExists(tableName):
        return self.openTable(tableName, asType=asType)
    else:
        return self.createTable(self, tableName, schema, asType=asType)

当我打电话时,我收到这样的错误:

TypeError: createTable() got multiple values for keyword argument 'asType'

有没有办法“通过”这样的关键字参数?

我想到了几个答案,但没有一个是最佳的。从最差到最好:

  • 我可以在一个或多个函数上更改关键字名称,但我想对所有三个函数使用相同的关键字,因为该参数具有相同的含义。

  • 我可以按位置而不是按关键字传递asType参数,但如果我将其他关键字参数添加到openTablecreateTable,我必须记住改变电话。我宁愿它自动适应,就像我可以使用关键字形式一样。

  • 我可以在这里使用**args表单来获取关键字参数的字典,而不是使用默认参数,但这似乎是使用大锤来拍打飞行(因为额外的行正确解析它所需的代码。)

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:9)

你做对了......在第二次函数调用中取出self:)

  return self.createTable(self, tableName, schema, asType=asType)

应该是:

  return self.createTable(tableName, schema, asType=asType)

答案 1 :(得分:5)

我不得不说,我首先想到的是一个更复杂的问题。但David Wolever的答案是完全正确的。这只是重复的自我,这就产生了问题。这样,位置参数变得不正常,asType被赋予一个值作为possitional参数(一次)和一个keyword-parameter(第二次!)。

更有趣的问题是,当你想要增强被调用的例程(示例中的createTable)而不是每次都增强中间函数时,该怎么做。在这里,** args解决方案成功:

例如:

def createOrOpenTable(self, tableName, schema, **args):
    if self.tableExists(tableName):
        return self.openTable(tableName, **args)
    else:
        return self.createTable(tableName, schema, **args)

通过这种方式,可以增强createTable和openTable的签名,而无需再更改createOrOpenTable。

当create和openTable可以有不同的关键字参数时,当然两个例程必须定义如下:

def createTable(self, tableName, schema, asType=None, **others):
   ...

其他参数会占用方法未知的任何关键字参数 - 评估它也不需要。

答案 2 :(得分:5)

我会在Juergen的帖子上发表评论,但我需要编写一个代码示例。这是一个更通用的版本:

def createOrOpenTable(self, tableName, schema, *args, **argd):
    if self.tableExists(tableName):
        return self.openTable(tableName, *args, **argd)
    else:
        return self.createTable(tableName, schema, *args, **argd)

这将允许位置参数也有效(如果你真的希望这是一个“传递”,这很重要。