2015-01-21 84 views
0

我曾想过以某种方式将字典附加到本地作用域,但是我也看到了类似的问题 - 通常是用“不这样做!”的响应。我会说明我的问题,并欢迎任何解决此问题的建议。Python方便地将字典参数传递给函数

如果有一个选项字典(从JSON中读取,所以不需要太多混乱),我决定通过这个如下;

def testParse(dataObj, userOptions): 

    # Merge default with passed options taking prescidence 
    defaultOpts = { 

     'boxheight' : 200, 
     'boxwidth' : 100, 
     'padding' : 150 

    } 
    opt = dict(userOptions.items() | defaultOpts.items()) 

问题是;有没有办法在字典中附加的每个值在局部范围使用,从而使密钥而不是复制出整个字典

boxheight = opt['boxheight'] 

等,或每次我指的是它的时间来写opt['boxheight']。我可以循环opt字典并以编程方式分配值吗?

我没有附加到概述的方法,但所有选项都将在某些时候用于本地表达式,并且从一开始就作为字典存在。非常感谢您的建议。

[免责声明:才开始工作与Python几天]

+0

不,对于局部变量没有办法做到这一点。在dicitonary中有多少项目?我建议明确的任务。 – 2015-01-21 11:34:41

+3

处理这个问题的最简单方法是给子函数使用关键字参数,然后将字典解压到调用中(例如'def func(padding,** kwargs)'然后'func(** opt)'会使' padding'在'func'中本地可用,并将其他所有内容封装到'kwargs'中)。 – jonrsharpe 2015-01-21 11:36:15

+0

@jonrsharpe - 美丽! – Joe 2015-01-21 11:42:11

回答

0

好,感谢@ jonrshapre的评论,我有以下解决方案

# user options 
userOps = { 'name' : 'joe', 'age' : 21 } 
data = (1,2) 

# default options specified as function argument 
def _func(data, name, lovesSO = True, **kwargs): 

    print(data) 
    print(name) 
    print(lovesSO) 
    print(kwargs) 

# Call 
_func(data, **userOps)  

# OUTPUTS 
# (1,2) 
# joe 
# True 
# {'age' : 21} 

价格本办法支付似乎稍微非传统的调用语法(虽然正如在评论中指出的那样,这对于像我这样的新人来说只是不寻常的)。然而,这可以通过定义

def func(data, options): _func(data, **options) 

或另一种解决方案基于@ Sven Marnach的评论;

# Utility options class 
class Options: 
    def __init__(self, defaults, user_opts): 
     vars(self).update(defaults) 
     vars(self).update(user_opts) 

def func2(data, userOps): 

    opt = Options({ 'lovesSO' : True}, userOps) 

    print(data) 
    print(opt.name) 
    print(opt.lovesSO) 

# Call  
func2(data, userOps) 

# OUTPUT 
# (1, 2) 
# joe 
# True 

这具有限定一个辅助类的缺点,但是具有明知哪些变量由opt.前缀的存在用户可定义的选项的好处。另外调用语法很自然。

在这两种情况下,未使用的用户选项均作为kwargs字典(在第一种情况下)或作为opt字典中未使用的条目存储。

我个人决定选择第二种解决方案。

+1

*“稍微非传统的调用语法”*似乎不准确 - “*”和“**”被广泛用于惯用的Python。还要注意,这些将以不同的方式使用 - 通过Sven的,您可以将一个名称空间对象**传递给** func2,其中包含所有用户选项,而不是在函数内部创建名称空间。 。 – jonrsharpe 2015-01-21 12:12:43

+0

感谢@jonrsharpe,现在会更新。 – Joe 2015-01-21 12:15:40

+0

@jonrsharpe。回复:斯文的做法;如果我在func2之外定义Namespace对象,那么默认选项会覆盖用户选项no?那么似乎我需要做一些重点检查? – Joe 2015-01-21 12:19:12