2012-05-08 2 views
10

Кажется, что многие аспекты python - всего лишь дубликаты функциональности. Есть ли какая-то разница за пределами избыточности, которую я вижу в kwargs и dict внутри Python?В чем разница между ** kwargs и dict в Python 3.2?

+4

'** kwargs' неявно создает * а *' dict' объект (названный 'kwargs'), загруженный ключами и значениями. Это не дублирующаяся функциональность. –

+0

Развернуть «многие аспекты». Какие еще области дублируют функциональность? – jdi

ответ

8

Существует разница в аргументе распаковка (где многие люди используют kwargs) и переходя dict в качестве одного из аргументов:

  • Использование аргумента распаковку:

    # Prepare function 
    def test(**kwargs): 
        return kwargs 
    
    # Invoke function 
    >>> test(a=10, b=20) 
    {'a':10,'b':20} 
    
  • пропускании Dict как аргумент:

    # Prepare function 
    def test(my_dict): 
        return my_dict 
    
    # Invoke function 
    >>> test(dict(a=10, b=20)) 
    {'a':10,'b':20} 
    

Различия в основном:

  • читаемость (вы можете просто передать ключевые аргументы, даже если они не были четко определены),
  • гибкость (вы можете поддержать некоторые именованные аргументы явно, а остальные с помощью **kwargs) ,
  • аргумент распаковка поможет избежать неожиданных изменений в объект «содержащий» аргументы (что менее важно, так как Python вообще предполагает, разработчики знают, что они делают, что это другая тема),
+4

С распаковкой ключи должны быть действительными идентификаторами –

+0

@gnibbler: Вы правы, +1. Я полностью пропустил это. В качестве примера я бы дал 'test ({0: 10, '0': 20})' (который вернет '{0: 10, '0': 20}'), который трудно заменить распаковкой аргумента. – Tadeck

3

Правильно, что в большинстве случаев вы можете просто обменять dicts и ** kwargs.

Например:

my_dict = {'a': 5, 'b': 6} 
def printer1(adict): 
    return adict 
def printer2(**kwargs): 
    return kwargs 

#evaluate: 
>>> printer1(my_dict) 
{'a': 5, 'b': 6} 
>>> printer2(**my_dict) 
{'a': 5, 'b': 6} 

Однако с kwargs у вас есть больше гибкости, если сочетать его с другими аргументами:

def printer3(a, b=0, **kwargs): 
    return a,b,kwargs 

#evaluate 
>>> printer3(**my_dict) 
(5, 6, {}) 
Смежные вопросы