2014-09-23 30 views
0

我在查询一个带有关于事件信息的API端点。尽管每个事件的属性数量可能会有所不同。我现在尝试执行以下操作:如何设置一个var,如果它存在于字典中?

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。是否有人知道我可以如何(Python)将属性设置为event,仅当它存在于e字典中?欢迎所有提示!

+0

看到@starrify的答案,它取决于你是否希望始终在'event'对象中拥有属性(或者使用来自dict的值或者使用None的值),或者根本不需要拥有它们不在字典中。换句话说,它取决于当密钥不在字典中时你想要做什么。 – zegkljan 2014-09-23 09:04:18

回答

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行的属性设置。

顺便说一句,在python文档内置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')...]这样的对列表,并通过这个对来获取和设置你的值。

相关问题