2011-10-07 21 views
5

Parsuję żądania JSON przy użyciu biblioteki JSON, która analizuje słownik Pythona. Ponieważ żądania są generowane przez użytkowników, muszę naprawić domyślne wartości dla parametrów, które nie zostały dostarczone. Inne języki mają takie cechy jak operatory potrójne, które mają sens w przypadku powtarzalnych aplikacji. Ale poniższy kod wymaga 4 linii na parametr.Jak naprawić domyślne wartości ze słownika Pythonically?

if "search_term" in request.keys(): 
    search_term=request['search_term'] 
else: 
    search_term="" 
if "start" in request.keys(): 
    start=request['start'] 
else: 
    start=0 
if "rows" in request.keys(): 
    rows=request['rows'] 
else: 
    rows=1000000 

Czy istnieje Pythoniczny sposób zmniejszenia linii kodu lub uczynienia go bardziej czytelnym?


Edit: Zarówno (u góry) odpowiedzi są równie przydatne. Kiedyś zarówno w różnych okolicznościach

+0

Ponieważ nikt inny nie zwrócił na to uwagę jeszcze linia: ** jeśli „wiersze” w request.keys(): ** to odpowiednik prostszego: ** jeśli "wiersze" w żądaniu: **. – MrWonderful

Odpowiedz

15

Użyj metody dict.update na kopii domyślnych:

defaults = dict(a=1, b=2, c=3) 

result = dict(defaults) # Copy the defaults 
result.update(request) # Update with your values 

To pozwala zachować defaults jako atrybut klasy lub zmiennej globalnej modułu, co prawdopodobnie chcesz zrobić.

Można również łączyć dwa ostatnie wiersze w:

result = dict(defaults, **request) 

innego rozwiązania, zobacz Kevin's answer.

+0

Podoba mi się to jako alternatywa dla dict.get(), ponieważ pozwala określić wszystkie domyślne wartości w jednym wierszu. Może to być użyteczne, jeśli twoje wartości domyślne prawdopodobnie ulegną zmianie w przyszłości - wtedy nie musisz szukać wielu instrukcji "if", aby znaleźć miejsce, w którym są zadeklarowane. – Kevin

+0

+1 - zapewnia jedno centralne miejsce do zarządzania ustawieniami domyślnymi i wysoce łatwą w utrzymaniu. Dobra odpowiedź! –

+2

+1. To doskonałe rozwiązanie. Muszę podkreślić, że ta metoda musi być używana z kopią "defaults", w przeciwnym razie 'defaults' zostanie zmodyfikowana. Ponadto nie można odwrócić logiki. Wykonanie 'request.update (defaults)' spowoduje nadpisanie żądania wartościami domyślnymi. –

12

Można użyć metody słownikowej get, której drugim argumentem jest wartość domyślna, którą należy zwrócić, jeśli w słowniku nie ma wartości.

start = request.get('start', 0) 
+0

+1 Ta metoda jest czytelna i łatwa do zrozumienia. Wolę, gdy nie ma zbyt wielu wartości z wartościami domyślnymi. –

+1

Chciałbym zaakceptować dwie odpowiedzi :-( – aitchnyu

2

słowniki Python posiada get() funkcję, która przyjmuje parametr domyślny (można sprawdzić, here). Możesz więc zrobić coś takiego:

params.get('search_term', '') 
params.get('some_other_field', 0) 

i tak dalej.

EDYCJA :: Prawdopodobnie będziesz chciał użyć rozwiązania update od Petra powyżej.

2

Jeśli masz szczęście wystarczy, aby użyć Python 3.3+, można użyć collections.ChainMap:

from collections import ChainMap 

defaults = {'color': 'red', 'taste': 'sweet'} 
request = {'taste': 'sour', 'size': 'small'} 

result = ChainMap(request, defaults) 

print(result['taste']) # sour -- overridden 
print(result['color']) # red -- from default 
print(result['size']) # small -- new value 

Zarówno defaults i request dicts są „powiązane” z ChainMap, nie kopiowane. Wszelkie zmiany do nich będą odzwierciedlone w result:

defaults['color'] = 'green' 
print(result['color']) # green 

del result['taste'] 
print(result['taste']) # sweet 

Aby temu zapobiec, można konwertować ChainMap do DICT kiedy skończysz go budować. Pomaga to także, jeśli trzeba radzić sobie z aroganckim kodu, który robi isinstance(result, dict):

print(dict(result)) 
# {'color': 'green', 'taste': 'sweet', 'size': 'small'} 
+0

Nicea. Istnieje również użyteczna implementacja 2.x ChainMap (pisana nieco inaczej) pod adresem http://code.activestate.com/recipes/305268/ (link znajduje się w 3.x docs, ale myślałem, że to też powinno wystarczyć) – torek

+0

@torek To prawda, ale chyba nie warto się tym przejmować. –

Powiązane problemy