Come verificare se esiste una chiave in ** kwargs?


111

Python 3.2.3. C'erano alcune idee elencate qui , che funzionano su normali var, ma sembra che ** kwargs giochi con regole diverse ... quindi perché non funziona e come posso verificare se esiste una chiave in ** kwargs?

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

Penso anche che dovrebbe funzionare, ma non è così -

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

Immagino perché kwargs è iterabile? Devo iterarlo solo per verificare se c'è una chiave particolare?


4
Non ci sono regole speciali. Hai appena dimenticato le virgolette.
Lennart Regebro

Risposte:


164

Tu vuoi

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

Per ottenere il valore di errormessage

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

In questo modo, kwargsè solo un altro dict. Il tuo primo esempio, if kwargs['errormessage']significa "ottieni il valore associato alla chiave" messaggio di errore "in kwargs, quindi controlla il suo valore bool". Quindi se non esiste una tale chiave, otterrai un file KeyError.

Il tuo secondo esempio if errormessage in kwargs:significa "se kwargscontiene l'elemento denominato da" errormessage"e, a meno che" errormessage"non sia il nome di una variabile, otterrai un NameError.

Dovrei menzionare che i dizionari hanno anche un metodo .get()che accetta un parametro predefinito (a sua volta predefinito None), in modo che kwargs.get("errormessage")restituisca il valore se quella chiave esiste e Nonealtrimenti (allo kwargs.get("errormessage", 17)stesso modo fa quello che potresti pensare che faccia). Quando non ti interessa la differenza tra la chiave esistente e quella avente Nonecome valore o la chiave non esistente, questo può essere utile.


Grazie per la spiegazione extra! È sempre utile per i nuovi arrivati ​​di Python ottenere alcune informazioni di base e ulteriori esempi di ciò che è possibile e cosa non lo è. In questo spirito: penso, kwargs.get("errormessage", 17)potrebbe restituire il suo valore o 17se il messaggio di errore non esiste, ma non ne sono sicuro. È corretto?
Honeybear

Ah sì lo fa. L'ho trovato qui . Grazie ... volevo solo essere sicuro.
Honeybear

21

Le risposte di DSM e Tadeck rispondono direttamente alla tua domanda.

Nei miei script uso spesso il comodo dict.pop()per trattare argomenti opzionali e aggiuntivi. Ecco un esempio di un semplice print()wrapper:

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

Poi:

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

Come puoi vedere, se prefixnon è contenuto in kwargs, il valore predefinito ''(stringa vuota) viene memorizzato nel file localprefix variabile . Se viene fornito, viene utilizzato il suo valore.

Questa è generalmente una ricetta compatta e leggibile per scrivere wrapper per qualsiasi tipo di funzione: sempre solo argomenti pass-through che non capisci e non sai nemmeno se esistono. Se passi sempre *argse**kwargs rendi il tuo codice più lento e richiede un po 'più di digitazione, ma se le interfacce della funzione chiamata (in questo caso print) cambiano, non è necessario modificare il codice. Questo approccio riduce i tempi di sviluppo supportando tutte le modifiche all'interfaccia.


Grazie per aver mostrato come assegnare un valore predefinito a prefix.
HB il

11

È solo questo:

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

Devi controllare se la chiave è nel dizionario. La sintassi per questo è some_key in some_dict(dovesome_key è qualcosa hashable, non necessariamente una stringa).

Le idee che hai collegato ( queste idee ) contenevano esempi per verificare se una chiave specifica esisteva nei dizionari restituiti da locals()e globals(). Il tuo esempio è simile, perché stai verificando l'esistenza di una chiave specifica nel kwargsdizionario (il dizionario contenente gli argomenti delle parole chiave).


3

Un modo è aggiungerlo da solo! Come? Fondendosi kwargscon un mucchio di impostazioni predefinite. Ciò non sarà appropriato in tutte le occasioni, ad esempio se le chiavi non ti sono note in anticipo. Tuttavia, se lo sono, ecco un semplice esempio:

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)

I valori predefiniti sono impostati nel dizionario args, che include tutte le chiavi che ci aspettiamo. Per prima cosa controlliamo per vedere se ci sono chiavi impreviste in kwargs. Quindi aggiorniamo argscon il kwargsquale sovrascriveremo eventuali nuovi valori che l'utente ha impostato. Non abbiamo bisogno di verificare se esiste una chiave, ora la usiamo argscome dizionario degli argomenti e non ne abbiamo più bisogno kwargs.


1

Puoi scoprire queste cose facilmente da solo:

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

hello(what="world")

13
Rimuovere il "facile" e quindi è una risposta migliore. Se fosse facile per tutti, non avremmo bisogno di questo sito. Trovare l' inoperatore in sé non è facile se non hai mai programmato e / o sei nuovo in Python. Viene solo accennato in dict.get()e dict.setdefault()help.
cfi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.