2013-06-05 3 views
1

Новое на Python/Django с PHP, и я пытаюсь обернуть мою голову вокруг этих примеров обновления() и получить() из этого примера:Команды словаря Python с динамическими функциями?

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

update(): Похоже, что это Дойна JQuery-иш типа обновления только для элементов, которые включены() ... которые я действительно не понимаю, как эта функция выходит из 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) 

ответ

5

dict.update() function может принимать Iterable из (key, value) пар; код, который у вас есть, проходит в generator expression, который создает такие пары. Он перемещается на sub.BACKENDS.items(), и для каждой пары выбираются только те, чей метод val.enabled() возвращает True. Вы можете выразить его как цикл, а также:

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

dict.get() функция возвращает либо ключ или значение по умолчанию. Здесь по умолчанию используется анонимная функция, lambda. Таким образом, словарь BACKEND либо имеет значение для ключа, названного в переменной name, либо возвращается анонимная функция лямбда. В любом случае, сам вызов вызова .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 are anonymous functions, который может быть определен в выражении (строка def functionname() является заявлением и должна стоять на ее собственном); лямбды, таким образом, может быть определено при хранении его в словарь непосредственно:

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

Спасибо @Martijn, это было очень полезно и подробно. Один вопрос, есть ли последствия памяти для помещения вызова функции в цикл for ex. для ключа, значение в sub.BACKENDS.items(): – daxiang28

+0

Асо, не был уверен, что это было daxiang28

+0

Нет, нет. Это просто ссылка. '' - это строка представления для этого объекта функции. CPython использует адрес памяти, чтобы помочь вам обнаружить разные объекты функций (в противном случае их было бы сложно сохранить отдельно). –

0

Попробую написать свой пример, но немного более ясно. см. объяснение в ответе @Martijn 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) 
+0

Спасибо @ Elazar. Также полезно увидеть этот синтаксис для заполнения dict. – daxiang28

Смежные вопросы