2012-09-13 14 views
55

Python 3.2.3. Hubo algunas ideas listed here, que funcionan en var's regulares, pero parece que ** kwargs se rigen por reglas diferentes ... ¿por qué no funciona esto y cómo puedo verificar si existe una clave en ** kwargs?¿Cómo verificar si existe una clave en ** kwargs?

if kwargs['errormessage']: 
    print("It exists") 

También creo que esto debería funcionar, pero no es así -

if errormessage in kwargs: 
    print("yeah it's here") 

supongo porque kwargs es iterable? ¿Debo repetirlo solo para verificar si hay una clave en particular?

+2

No hay reglas especiales. Simplemente olvidaste las comillas. –

Respuesta

86

¿Quieres

if 'errormessage' in kwargs: 
    print("found it") 

Para obtener el valor de errormessage

if 'errormessage' in kwargs: 
    print("errormessage equals " + kwargs.get("errormessage")) 

De esta manera, kwargs es sólo otro dict. Su primer ejemplo, if kwargs['errormessage'], significa "obtener el valor asociado con la clave" mensaje de error "en kwargs, y luego verifique su valor bool". Entonces, si no hay tal clave, obtendrá un KeyError.

Su segundo ejemplo, if errormessage in kwargs:, significa "si kwargs contiene el elemento nombrado por" errormessage", ya menos que 'errormessage' es el nombre de una variable, obtendrá un NameError.

Debo mencionar que Los diccionarios también tienen un método .get() que acepta un parámetro predeterminado (predeterminado en None), por lo que kwargs.get("errormessage") devuelve el valor si esa clave existe y None de lo contrario (de manera similar, kwargs.get("errormessage", 17) hace lo que usted podría pensar que es). Cuando no le importa la diferencia entre la clave existente y que tiene None como valor o la clave no e xisting, esto puede ser útil.

8

Es precisamente esta:

if 'errormessage' in kwargs: 
    print("yeah it's here") 

Es necesario comprobar, si la clave está en el diccionario. La sintaxis para eso es some_key in some_dict (donde some_key es algo hashable, no necesariamente una cadena).

Las ideas que ha vinculado (these ideas) contenían ejemplos para comprobar si existía una clave específica en los diccionarios devueltos por locals() y globals(). Su ejemplo es similar, porque está comprobando la existencia de una clave específica en el diccionario kwargs (el diccionario que contiene argumentos de palabra clave).

1

se puede descubrir esas cosas fácilmente por sí mismo:

def hello(*args, **kwargs): 
    print kwargs 
    print type(kwargs) 
    print dir(kwargs) 

hello(what="world") 
+3

Eliminar el "fácil" y luego es una mejor respuesta. Si fuera fácil para todos, entonces no necesitaríamos este sitio. Encontrar el operador 'in' en sí mismo no es fácil si nunca has programado y/o eres nuevo en Python. Solo se insinúa en la ayuda 'dict.get()' y 'dict.setdefault()'. – cfi

2

Una forma es añadir usted mismo! ¿Cómo? Al combinar kwargs con un montón de valores predeterminados. Esto no será apropiado en todas las ocasiones, por ejemplo, si las claves no se conocen con anticipación. Sin embargo si lo son, aquí está un ejemplo sencillo:

import sys 

def myfunc(**kwargs): 
    args = {'country':'England','town':'London', 
      'currency':'Pound', 'language':'English'} 

    diff = set(kwargs.keys()) - set(args.keys()) 
    if diff: 
     print("Invalid args:",tuple(diff),file=sys.stderr) 
     return 

    args.update(kwargs)    
    print(args) 

Los valores por defecto se establecen en el diccionario args, que incluye todas las claves que estamos esperando. Primero verificamos si hay claves inesperadas en kwargs.Luego actualizamos args con kwargs, que sobrescribirá cualquier valor nuevo que el usuario haya establecido. No es necesario que verifiquemos si existe una clave, ahora usamos args como nuestro diccionario de argumentos y ya no necesitamos kwargs.

11

Las respuestas de DSM y Tadeck responden a su pregunta directamente.

En mis scripts a menudo uso el conveniente dict.pop() para tratar argumentos adicionales y opcionales. Aquí está un ejemplo de un simple print() envoltorio:

def my_print(*args, **kwargs): 
    prefix = kwargs.pop('prefix', '') 
    print(prefix, *args, **kwargs) 

continuación:

>>> my_print('eggs') 
eggs 
>>> my_print('eggs', prefix='spam') 
spam eggs 

Como se puede ver, si prefix no está contenido en kwargs, el valor por defecto '' (cadena vacía) se almacena en la variable local prefix. Si se da, entonces su valor está siendo utilizado.

Por lo general, esta es una receta compacta y fácil de leer para cualquier tipo de función: siempre pasa a través de argumentos que no comprende, y ni siquiera sabe si existen. Si siempre pasa por *args y **kwargs, hace que su código sea más lento y requiere un poco más de tipeo, pero si las interfaces de la función llamada (en este caso print) cambian, no necesita cambiar su código. Este enfoque reduce el tiempo de desarrollo al tiempo que admite todos los cambios de interfaz.

Cuestiones relacionadas