任务是将字段从一个数据集映射到另一个,某些字段需要一些额外的解析/计算。
((在下面提供的示例中,我仅使用了几个字段,但是原始数据集中还有很多字段。)>
起初,我虽然将dict用于字段映射,而只是将函数分配给需要其他数据操作的键:
import base64 import hashlib import json from datetime import datetime def str2base64(event): md5 = hashlib.md5(event['id'].encode()) return base64.b64encode(md5.digest()) def ts2iso(event): dt = datetime.fromtimestamp(event['timestamp']) return dt.isoformat() MAPPINGS = { 'id': id2hash, 'region': 'site', 'target': 'host', 'since': ts2iso } def parser(event): new = dict() for k, v in MAPPINGS.items(): if callable(v): value = v(event) else: value = event.get(v) new[k] = value return new def main(): for event in events: # dicts event = parser(event) print(json.dumps(event, indent=2)) if __name__ == '__main__': main()
我不喜欢这样的事实,我必须在顶部添加所有解析函数,以便MAPPING字典可以看到它,而且我不确定这是否是最佳方法吗?此外,我看不到在
dict.get
函数中将默认值传递给parser
的简便方法。
import base64
import hashlib
import json
from datetime import datetime
class Event(object):
def __init__(self, event):
self.event = event
@property
def id(self):
md5 = hashlib.md5(self.event['id'].encode())
return base64.b64encode(md5.digest())
@property
def region(self):
return self.event['site']
@property
def target(self):
return self.event['host']
@property
def since(self):
dt = datetime.fromtimestamp(self.event['timestamp'])
return dt.isoformat()
def data(self):
return {
attr: getattr(self, attr)
for attr in dir(self)
if not attr.startswith('__') and attr not in ['event', 'data']
}
def main():
for event in events: # dicts
event = Event(event).data()
print(json.dumps(event, indent=2))
if __name__ == '__main__':
main()
我确定有更好的方法来获取所有属性(仅适用于产权方法),以避免这种丑陋的data
方法?我还想避免在相关方法中添加前缀,以便随后可以使用str.startswith
或类似内容对其进行过滤。
此任务的最佳方法是什么?我也在看functools的@functools.singledispatch,但我认为在这种情况下它不会有帮助。
任务是将字段从一个数据集映射到另一数据集,某些字段需要一些额外的解析/计算。 (在下面提供的示例中,我仅使用了几个字段,但还有更多...
我认为您的第一种方法很有道理,并且,如果这对您很重要,则其性能将比OO方法好得多。万一您需要处理大量事件,将dict
转换为object
当然会占用大量CPU。我发现它也非常明确。
我喜欢@matino的答案,但是我想提出一些相关的观点: