2009-06-19 75 views
4

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

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表单而不是使用默认参数来获取关键字参数的字典,但这似乎是使用大锤猛击苍蝇(因为需要额外的代码行来正确解析它)。

有没有更好的解决方案?

回答

9

你这样做是正确的...只是拿出第二函数调用了:) self

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

应该是:

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

D'哦正如!可能很明显,我对Python还是个新手,感谢您指出了这个问题 – 2009-06-19 14:50:12

+0

没问题:) 虽然Python总体来说还是很不错的,但是这些小小的“陷阱”中很少有这些会严重烧毁你当你第一次打他们。如果你还没有定义一个没有“自我”参数的方法,你会击中的另一个......你的程序将死于一个非常有用的“不正确的参数数量”错误。 – 2009-06-19 16:29:49

+0

是的,我早打了。幸运的是,我很快就接触到了这个问题。 – 2009-06-20 02:23:15

5

我不得不说,我第一次想到更复杂的问题。但大卫沃勒弗的回答绝对正确。这只是重复的自我,造成了这个问题。通过这种方式,位置参数脱节并且asType被赋予一个值作为possitional参数(一次)和关键字参数(第二次!)。

一个更有趣的问题是,当你想增强被调用的例程(例子中的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更多。

当创建和OpenTable的可以有不同的关键字参数,那么当然既例程必须定义如下:

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

其余参数吃掉未知的方法的任何关键字参数 - 它也是不需要评估它。

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) 

这将使位置参数也有效(这是很重要的,如果你真的希望这是一个