我查询带有事件信息的API端点。但是,每个事件的属性数量可能会有所不同。我现在尝试执行以下操作:
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 :(得分:2)
我建议使用属性列表和for循环使用if。像这样:
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内置setattr
https://docs.python.org/2/library/functions.html#setattr
答案 1 :(得分: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
答案 2 :(得分: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')...]
这样的对的列表,并使用这些对来获取和设置你的值。