Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 传递关键字参数_Python - Fatal编程技术网

Python 传递关键字参数

Python 传递关键字参数,python,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, asTy

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

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
    参数,但是如果我将其他关键字参数添加到
    openTable
    createTable
    ,我必须记住更改调用。我宁愿它自动适应,就像我可以使用关键字表单一样

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


有更好的解决方案吗?

你做得对。。。只需在第二个函数调用中取出
self
:)

应该是:

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

我不得不说,我首先想到了一个更复杂的问题。但大卫·沃勒夫的答案绝对正确。正是这个重复的自我造成了这个问题。通过这种方式,位置参数变得不一致,asType被赋予一个值作为占有参数(一次)和关键字参数(第二次!)

一个更有趣的问题是,当您想要增强被调用的例程(本例中为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的签名,而无需再更改CreateOrPentable

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

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

others参数会吞噬该方法未知的任何关键字参数——也不需要对其求值。

我本来会在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)

这将允许位置参数也有效(如果您真的希望它成为“传递”,这一点很重要。”

D'oh!很明显,我对Python还是新手。感谢您指出问题。没问题:)虽然Python总体上相当不错,但这些小“陷阱”却很少当你第一次打他们的时候会把你烧得很厉害。如果您还没有定义一个没有“self”参数的方法,那么您将遇到另一个问题。。。你的程序会因为一个非常有用的“参数数目不正确”错误而死掉。是的,我很早就发现了。幸运的是,我很快就明白了这一点。嗨,杰森,谢谢你提供了更通用的解决方案!我没有考虑它,因为在我的实践中,它只是出现了,需要额外的可选参数(实际上是关键字参数)——没有占有参数。当然,可能会有额外的占有参数,但大多数情况下,您的主接口都会被修复——并且将来只会弹出可选参数。这是真的。为了完整起见,我只是指出了这一点。:-)@JasonBaker这里的
**argd
是什么?你的意思是
**kwargs
,还是它们是一样的东西?我似乎找不到有关
**argd
。。。
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)