2014-09-23 3 views
0

Я обращаюсь к конечной точке API, которая предоставляет информацию о событиях. Количество атрибутов каждого события может меняться. Теперь я пытаюсь сделать следующее:Как установить var, если он существует в dict?

for e in apiResult: 
    event = Event() 
    event.street = e['f_street'] 
    event.price = e['f_price'] 
    event.venue_name = e['f_venue_name'] 
    event.start = e['f_start'] 
    # and about 40 more.. 
    event.save() 

Но иногда я получаю ключевые ошибки. Поэтому для каждого атрибута мне нужно проверить, существует ли он. Я мог бы, конечно, сделать это следующим образом:

if 'f_street' in e: 
    event.street = e['f_street'] 
if 'f_price' in e: 
    event.price = e['f_price'] 
# etc. etc. 

но это не похоже на Pythonic. Кто-нибудь знает, как я могу (Pythonically) установить атрибут event, только если он существует в словаре e? Все советы приветствуются!

+0

Увидев ответ @starrify, это зависит от того, хотите ли вы всегда иметь атрибуты в объекте 'event' (либо со значением из dict или с параметром None), либо не иметь их вообще, когда ключ не находится в словаре. Другими словами, это зависит от того, что именно вы хотите сделать, когда ключ не находится в словаре. – zegkljan

ответ

2

Я бы рекомендовал использовать список атрибутов и для цикла с если. Что-то вроде этого:

attrs = ['f_street', 'f_price', 'etc'] 
    ... 
    for e in apiResult: 
     event = Event() 
     for attr in attrs: 
      if attr in e: 
       setattr(event, attr, e[attr]) 
     event.save() 

Это также устранит 40 строк настроек атрибутов.

Btw, документы на питона встроенные setattrhttps://docs.python.org/2/library/functions.html#setattr

1

dict.get поможет:

Help on built-in function get: 

    get(...) method of builtins.dict instance 
    D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. 

Таким образом, вы могли бы написать так:

# instead of this: 
# event.start = e['f_start'] 
event.start = e.get('f_start') # And it would be None if key not exists 
1

Вы можете написать функцию для этого:

def set_if_present(obj, attr_name, dictionary, key): 
    if key in dictionary: 
     setattr(obj, attr_name, dictionary[key]) 

Чем вы можете использовать его как это:

>>> class O(object): 
...  pass 
... 
>>> d = {"a": 0, "b": 1} 
>>> o = O() 
>>> set_if_present(o, "a", d, "a") 
>>> set_if_present(o, "b", d, "b") 
>>> set_if_present(o, "c", d, "c") 
>>> o.a 
0 
>>> o.b 
1 
>>> o.c 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'O' object has no attribute 'c' 
>>> 

или в вашем случае

for e in apiResult: 
    event = Event() 
    set_if_present(event, 'street', e, 'f_street') 
    set_if_present(event, 'price', e, 'f_price') 
    set_if_present(event, 'venue_name', e, 'f_venue_name') 
    set_if_present(event, 'start', e, 'f_start') 
    # and about 40 more.. 
    event.save() 

Чтобы быть еще более pythonic, вы можете создать список пар, например [('street', 'f_street'), ('price', 'f_price')...], и пройти через это, используя пары, чтобы получить и установить ваши значения.

Смежные вопросы