带有动态函数的Python字典命令



从PHP到Python/Django的新手,我试图从这个例子中了解这些update()和get()的例子:

https://pypi.python.org/pypi/django-social-auth/0.3.0

update():看起来像是只对启用的项进行查询式更新()…我真的不明白这个函数是怎么从val中出来的

            backends.update(((key, val)
                for key, val in sub.BACKENDS.items()
                    if val.enabled()))

get():为什么有两组()() ?

BACKENDS.get(name, lambda *args, **kwargs: None)(*args, **kwargs)

dict.update()函数可以接受一个(key, value)对的可迭代对象;这里的代码传递一个生成这种对的生成器表达式。它循环sub.BACKENDS.items(),对于每一对只选择val.enabled()方法返回True的那些。您也可以将其表示为for循环:

for key, value in sub.BACKENDS.items():
    if value.enabled():
        backends[key] = value

dict.get()函数返回键或默认值。这里的默认值是一个匿名函数,lambda。因此,BACKEND字典要么为name变量中命名的键提供一个值,要么返回一个lambda匿名函数。无论哪种方式,调用.get()的结果本身都会被调用。在Python中,函数是一等对象;你也可以将它们存储在字典中;如果您从字典中检索一个,您仍然可以调用它:

>>> def foo(): print 'bar'
... 
>>> somedict = {'howdy': foo}
>>> somedict['howdy']()
bar
>>> somedict['howdy']
<function foo at 0x109ab9320>
>>> somedict.get('non-existent', 'not found')
'not found'
>>> somedict.get('howdy', 'not found')
<function foo at 0x109ab9320>
>>> somedict.get('howdy', 'not found')()
bar

因此,.get()之后的额外()应用于.get()返回的任何内容。

Lambdas是可以在表达式中定义的匿名函数(def functionname()行是一个语句,必须独立存在);因此,Lambdas可以在直接存储到字典中时定义:

>>> somedict = {'howdy': lambda: 'bar'}
>>> print somedict['howdy']()
bar

我将试着写出您的示例,但要更清楚一些。见@ martjn Pieters的解释

new_items = [(key, func) for key, func in sub.BACKENDS.items() if func.enabled()]
backends.update(new_items)
def do_nothing(*args, **kwargs):
    pass
func = BACKENDS.get(name, do_nothing)
func(*args, **kwargs)

最新更新