Jak sprawdzić, czy klucz w ** kwargs istnieje?


111

Python 3.2.3. Było kilka pomysłów wymienione poniżej , które działają na regularne var, ale wydaje się, ** kwargs grać według różnych zasad ... więc dlaczego nie ta praca i jak mogę sprawdzić, czy klucz w ** kwargs istnieje?

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

Myślę też, że to powinno działać, ale tak nie jest -

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

Zgaduję, ponieważ kwargs jest iterowalny? Czy muszę go powtarzać, aby sprawdzić, czy jest tam określony klucz?


4
Nie ma specjalnych zasad. Po prostu zapomniałeś cytatów.
Lennart Regebro,

Odpowiedzi:


165

Chcesz

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

Aby uzyskać wartość errormessage

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

W ten sposób kwargsjest po prostu kolejnym dict. Twój pierwszy przykład if kwargs['errormessage']oznacza „pobierz wartość skojarzoną z kluczem„ errormessage ”w kwargs, a następnie sprawdź jego wartość bool”. Więc jeśli nie ma takiego klucza, otrzymasz plik KeyError.

Twój drugi przykład if errormessage in kwargs:oznacza „jeśli kwargszawiera element o nazwie„ errormessage”i jeśli„ errormessage”nie jest nazwą zmiennej, otrzymasz plik NameError.

Powinienem wspomnieć, że słowniki mają również metodę, .get()która akceptuje domyślny parametr (sam domyślny None), więc kwargs.get("errormessage")zwraca wartość, jeśli ten klucz istnieje i w Noneprzeciwnym razie (podobnie kwargs.get("errormessage", 17)robi to, co myślisz, że robi). Jeśli nie zależy ci na różnicy między kluczem istniejącym a posiadaniem Nonejako wartości lub kluczem nieistniejącym, może to być przydatne.


Dzięki za dodatkowe wyjaśnienie! Zawsze dobre dla nowicjuszy Pythona, aby uzyskać podstawowe informacje i dalsze przykłady tego, co jest możliwe, a co nie. W tym duchu: myślę, że kwargs.get("errormessage", 17)może zwrócić swoją wartość lub 17jeśli komunikat o błędzie nie istnieje - ale nie jestem pewien. Czy to jest poprawne?
Honeybear

Ach tak, to prawda. Znalazłem to tutaj . Dzięki ... chciałem się tylko upewnić.
Honeybear

21

Odpowiedzi DSM i Tadeck odpowiadają bezpośrednio na twoje pytanie.

W moich skryptach często korzystam z wygodnych dict.pop()argumentów opcjonalnych i dodatkowych. Oto przykład prostego print()opakowania:

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

Następnie:

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

Jak widać, jeśli prefixnie występuje w kwargs, to domyślny ''(pusty ciąg) jest przechowywany w prefixzmiennej lokalnej . Jeśli jest podana, używana jest jej wartość.

Generalnie jest to zwarty i czytelny przepis na pisanie opakowań dla dowolnego rodzaju funkcji: zawsze przekazuj argumenty, których nie rozumiesz i nawet nie wiesz, czy one istnieją. Jeśli zawsze przechodzisz *argsi **kwargsrobisz swój kod wolniej i wymaga trochę więcej pisania, ale jeśli interfejsy wywoływanej funkcji (w tym przypadku print) ulegną zmianie, nie musisz zmieniać swojego kodu. Takie podejście skraca czas programowania, jednocześnie obsługując wszystkie zmiany interfejsu.


Dziękujemy za pokazanie, jak przypisać wartość domyślną do prefix.
HBat

11

Po prostu to:

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

Musisz sprawdzić, czy klucz jest w słowniku. Składnia tego jest następująca some_key in some_dict(gdzie some_keyjest coś haszującego, niekoniecznie ciąg znaków).

Pomysły, które połączyłeś ( te pomysły ), zawierały przykłady sprawdzania, czy określony klucz istnieje w słownikach zwróconych przez locals()i globals(). Twój przykład jest podobny, ponieważ sprawdzasz istnienie określonego klucza w kwargssłowniku (słownik zawierający argumenty słów kluczowych).


3

Jednym ze sposobów jest dodanie go samodzielnie! W jaki sposób? Łącząc się kwargsz kilkoma domyślnymi plikami. Nie będzie to właściwe za każdym razem, na przykład, jeśli klucze nie są ci z góry znane. Jeśli jednak tak jest, oto prosty przykład:

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)

Wartości domyślne są ustawione w słowniku args, który obejmuje wszystkie oczekiwane klucze. Najpierw sprawdzamy, czy w kwargach są jakieś nieoczekiwane klucze. Następnie aktualizujemy, za argspomocą kwargsktórych nadpisze się wszelkie nowe wartości ustawione przez użytkownika. Nie musimy sprawdzać, czy klucz istnieje, teraz używamy go argsjako naszego słownika argumentów i nie potrzebujemy go dalej kwargs.


1

Możesz łatwo odkryć te rzeczy samodzielnie:

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

hello(what="world")

13
Usuń „łatwe”, a wtedy będzie lepsza odpowiedź. Gdyby to było łatwe dla każdego, nie potrzebowalibyśmy tej strony. Znalezienie inoperatora samego w sobie nie jest łatwe, jeśli nigdy nie programowałeś i / lub nie znasz Pythona. To jest tylko zasugerował w dict.get()i dict.setdefault()pomoc.
cfi

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.