我正在编写一个小应用程序,并且希望保留人类可读的审计记录,以记录对数据库的任何更改(因此,有意避免使用记录更改写入数据库的工具)
下面的代码可以工作,但是一点也不优雅。您能用一种更优雅的方法来实现这一点吗?
def auditdiff(set1, set2):
new = set(set1.items())
old = set(session[set2].items())
diffset = dict(old ^ new) # holds what has changed
m = {}
for d in diffset:
for pair in old:
if pair[0] == d:
m[d + " OLD"] = pair[1]
for pair in new:
if pair[0] == d:
m[d + " NEW"] = pair[1]
return(m)
以下是调试器捕获的变量示例:
set1 :(旧值)
<class 'dict'>: {'date': '2019-04-25', 'student_id': None, 'booking_id': '', 'key': '', 'status': 'ATTEND', 'note': 'this is a changed note', 'charge': False}
set2 :(新值)
<class 'set'>: {('date', '2019-04-25'), ('note', 'this is a note'), ('student_id', None), ('charge', False), ('key', ''), ('status', 'ATTEND'), ('booking_id', '')}
diffset :(差异)
<class 'dict'>: {'note': 'this is a changed note'}
m :(新旧更改的值)
<class 'dict'>: {'note OLD': 'this is a note', 'note NEW': 'this is a changed note'}
亲切的问候
詹姆斯
答案 0 :(得分:2)
这样的事情怎么样? auditdiff
在这里接受两个字典并生成描述更改的4元组:
added
/ removed
/ changed
更改始终按字典的键顺序发出。
def auditdiff(d1, d2):
for key in sorted(set(d1) | set(d2)):
if key in d1 and key not in d2:
yield (key, "removed", d1[key], None)
elif key in d2 and key not in d1:
yield (key, "added", None, d2[key])
elif d1[key] != d2[key]:
yield (key, "changed", d1[key], d2[key])
d1 = {
"date": "2019-04-25",
"student_id": None,
"booking_id": "",
"key": "",
"status": "ATTEND",
"note": "this is a changed note",
"charge": False,
"greeting": "hello", # this was added c.f. the original demo data
}
d2 = {
"charge": False,
"note": "this is a note",
"key": "",
"date": "2019-04-25",
"student_id": None,
"status": "ATTEND",
"booking_id": "",
"hello": "world", # this was added c.f. the original demo data
}
for difference in auditdiff(d1, d2):
print(difference)
输出
('greeting', 'removed', 'hello', None)
('hello', 'added', None, 'world')
('note', 'changed', 'this is a changed note', 'this is a note')
答案 1 :(得分:0)
一些异想天开的解决方案:
d1 = {
"date": "2019-04-25",
"student_id": None,
"booking_id": "",
"key": "",
"status": "ATTEND",
"note": "this is a changed note",
"charge": False,
"greeting": "hello", # this was added c.f. the original demo data
}
d2 = {
"charge": False,
"note": "this is a note",
"key": "",
"date": "2019-04-25",
"student_id": None,
"status": "ATTEND",
"booking_id": "",
"hello": "world", # this was added c.f. the original demo data
}
class LabeledTuple(tuple):
def __new__(cls, t, label):
result = super().__new__(cls, t)
result.label = label
return result
def __repr__(self):
return self.label + super().__repr__()
def labeled_set(d, name):
return {LabeledTuple(t, name) for t in d.items()}
print(sorted(labeled_set(d1, "OLD") ^ labeled_set(d2, "NEW")))
# [OLD('greeting', 'hello'), NEW('hello', 'world'), OLD('note', 'this is a changed note'), NEW('note', 'this is a note')]
答案 2 :(得分:0)
这是基于您的解决方案。假定两个词典具有相同的键。
d1 = {
"date": "2019-04-25",
"student_id": None,
"booking_id": "",
"key": "",
"status": "ATTEND",
"note": "this is a changed note",
"charge": False,
}
d2 = {
"charge": False,
"note": "this is a note",
"key": "",
"date": "2019-04-25",
"student_id": None,
"status": "ATTEND",
"booking_id": "",
}
diffset = dict(set(d1.items()) ^ set(d2.items())) # holds what has changed
m = {}
for key in diffset:
m[key + " OLD"] = d1[key]
m[key + " NEW"] = d2[key]
print(m)