¿Cómo Comprobar Si Existe Una Clave en **kwargs?


Python 3.2.3. Había algunas ideas listadas aquí, que funcionan en var regulares, pero parece que **kwargs juega con reglas diferentes... entonces, ¿por qué esto no funciona y cómo puedo verificar si existe una clave en **kwargs?

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

También creo que esto debería funcionar, pero no doesn

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

Supongo que porque kwargs es iterable? ¿Tengo que iterar a través de ella solo para comprobar si hay una clave en particular?

Author: ROMANIA_engineer, 2012-09-13

5 answers

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 solo otro dict. Su primer ejemplo, if kwargs['errormessage'], significa "obtener el valor asociado con la clave "errormessage" en kwargs, y luego comprobar su valor bool". Así que si no hay tal clave, obtendrá un KeyError.

Su segundo ejemplo, if errormessage in kwargs:, significa "si kwargs contiene el elemento nombrado por "errormessage", y a menos que "errormessage" sea 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 por defecto (a su vez por defecto a None), de modo 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 podría pensar que hace). Cuando no le importa la diferencia entre la clave existente y tener None como valor o la clave no existente, esto puede ser útil.

 101
Author: DSM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-07 16:05:59

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

En mis scripts a menudo uso el conveniente dict.pop() para tratar con argumentos opcionales y adicionales. Este es un ejemplo de una envoltura simple print():

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

Entonces:

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

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

Esto es generalmente un compacto y receta legible para escribir envoltorios para cualquier tipo de función: Siempre solo pasa argumentos que no entiendes, y ni siquiera sabes si existen. Si siempre pasa a través de *args y **kwargs hace que su código sea más lento, y requiere un poco más de escritura, 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.

 16
Author: cfi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-14 07:08:49

Es solo esto:

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 (estas ideas) contenían ejemplos para verificar 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 palabras clave).

 8
Author: Tadeck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:59

Una manera es agregarlo usted mismo! ¿Cómo? Fusionando kwargs con un montón de valores predeterminados. Esto no será apropiado en todas las ocasiones, por ejemplo, si las claves no se conocen de antemano. Sin embargo, si lo son, aquí hay un ejemplo simple:

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 predeterminados se establecen en el diccionario args, que incluye todas las claves que esperamos. Primero comprobamos si hay claves inesperadas en kwargs. Luego actualizamos args con kwargs que sobrescribirá cualquier valor nuevo que el usuario se ha establecido. No necesitamos probar si existe una clave, ahora usamos args como nuestro diccionario de argumentos y no necesitamos más kwargs.

 2
Author: cdarke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-13 07:57:33

Puedes descubrir esas cosas fácilmente por ti mismo:

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

hello(what="world")
 1
Author: Christian Thieme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-13 07:24:24