使用非字符串关键字传递dicts

时间:2014-04-20 21:16:10

标签: python dictionary

似乎无法将带有非字符串关键字的dicts传递给Python中的函数。 (我看到这是在here

之前提出来的

然而,在对我的问题提出某种复杂的解决方案之前,我想我会问专家,看看是否有我遗漏的东西。 不幸的是,如果没有重要的重新分解,我无法轻易改变这种范式,因为之前的作者从未预料到这种类型的行为(这是一个非常简单的例子)。

我有一个名为services的对象可以对nodes执行操作。有些nodes需要不同的service配置。我每个service都有一个实例,而不是每个node的{​​{1}}个实例,然后我会根据每个service的配置参数进行组合。 node及其相应的配置参数存储在service

dict及其node及其相应的配置参数都会传递给函数(services),然后处理所有内容。此函数必须能够调用属于setupServices对象的函数。不幸的是,这失败了错误:

service

如果您想知道将TypeError: setupServices() keywords must be strings 传递给**nodeServices的是什么,而不仅仅是nodeServices,那么它就是下面的代码段(在这种情况下,值将是nodeServices)。我犹豫是否要将此代码专用于个案,因为它充当了许多其他事物的支柱。

if type( value ) is list:
    result = f( *value )
elif type( value ) is dict:
    result = f( **value )
else:
    result = f( value )
results[ name ] = result
return result

还有其他方法可以通过最少的修改来实现这一目标吗?

"A node can be associated with many services"
class Node(object):
    pass

"""Setup services routine (outside of the node due to an existing design choice)
   I could rewrite, but this would go against the existing author's paradigms"""
def setupServices ( node, **nodeServices ):
    for object, objOverrides in nodeServices.items():
        "do something with the service object"

"2 simple services that can be perform actions on nodes"
class serviceA(object):
    pass

class serviceB(object):
    pass

"instantiate an object of each service"
a = serviceA()
b = serviceB()

"Create a node, assign it two services with override flags"
node = Node()
nodeServices = {}
nodeServices[a] = { 'opt1' : True }
nodeServices[b] = { 'opt2' : False }

"Pass the node, and the node's services for setup"
setupServices ( node, **nodeServices )

1 个答案:

答案 0 :(得分:2)

更改它的最简单方法是更改​​setupServices,使其不再接受关键字参数,而只接受选项的字典。也就是说,将其定义更改为:

def setupServices (node, nodeServices):

(删除**)。然后,您可以使用setupServices(node, nodeServices)调用它。

唯一的缺点是你必须传入一个dict,并且不能传递文字关键字参数。使用关键字参数设置,您可以调用setupServices(node, opt1=True),但没有关键字参数,如果您想指定该选项“内联”,则必须执行setupServices(node, {'opt1': True}),传入文字字典。但是,如果你总是以编程方式创建一个选项词典,然后用**传递它,那么这个缺点并不重要。只有当你实际上有代码传递像setupServices(node, foo=bar)这样的文字关键字参数时才重要。

正如你所链接的问题中的答案所说,没有办法让函数接受非字符串关键字参数。因此,当foo(**nodeServices)的键不是字符串时,您无法使nodeServices工作。 (鉴于此,有点难以理解这个方案是如何工作的,因为在你的例子中,似乎setupServices总是期待一个dict,其键是服务对象,这意味着将它们作为关键字参数传递永远不会已经工作了。)