2012-05-08 18 views
10

Parece que muchos aspectos de python son solo duplicados de funcionalidad. ¿Hay alguna diferencia más allá de la redundancia que estoy viendo en kwargs y dict dentro de Python?¿Cuál es la diferencia entre ** kwargs y dict en Python 3.2?

+4

'** kwargs' crea implícitamente * a *' dict' objeto (nombrado por 'kwargs') cargado con claves y valores. Esto no es una funcionalidad duplicada. –

+0

Expandir en "muchos aspectos". ¿Qué otras áreas son funciones duplicadas? – jdi

Respuesta

8

Hay una diferencia en el argumento de desempacar (donde muchas personas utilizan kwargs) y que pasa dict como uno de los argumentos:

  • Usando el argumento de desembalaje:

    # Prepare function 
    def test(**kwargs): 
        return kwargs 
    
    # Invoke function 
    >>> test(a=10, b=20) 
    {'a':10,'b':20} 
    
  • El paso de un dict como un argumento:

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

Las diferencias son en su mayoría:

  • facilidad de lectura (se puede simplemente pasar argumentos de palabras clave, incluso si no se definen explícitamente),
  • flexibilidad (que puede soportar algunos argumentos clave explícita y el resto mediante **kwargs) ,
  • argumento desembalaje le ayuda a evitar cambios inesperados en el objeto "que contiene" los argumentos (que es menos importante, ya que, en general, Python asume desarrolladores saben lo que están haciendo, que es un tema diferente),
+4

Con desembalaje, las claves deben ser identificadores válidos –

+0

@gnibbler: Tiene razón, +1. Eché de menos eso. Como ejemplo daría 'test ({0: 10, '0': 20})' (que devolverá '{0: 10, '0': 20}'), que es difícil de reemplazar con el desempaquetado de argumentos. – Tadeck

3

Es correcto que en la mayoría de los casos puede simplemente intercambiar dicts y ** kwargs.

Por ejemplo:

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} 

Sin embargo, con kwargs que tenga más flexibilidad si se combina con otros argumentos:

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

#evaluate 
>>> printer3(**my_dict) 
(5, 6, {}) 
Cuestiones relacionadas