Python继承最佳实践对象历史记录'

时间:2016-04-28 02:50:13

标签: python python-2.7

我有很多课程(例如联系人)我也想跟踪更改历史记录。以下是我的出发点。我想这是一个常见的用例,所以希望能够在这里获得有关最佳实践的指导。这是一个使用多重继承的好地方,那会是什么样的?

from datetime import date

class ContactHistory(object):
    def __init__(self, contact, change_action, change_user_id, change_source):
        self.name = contact.name
        self.phone = contact.phone
        self.email = contact.email
        self.change_action = change_action
        self.change_user_id = change_user_id
        self.change_source = change_source
        self.change_date = date.today()

    def __repr__(self):
        return '%s, %s, %s, %s, %s, %s, %s' % (self.name, self.email, self.phone, self.change_action, self.change_user_id, self.change_source, self.change_date)

class Contact(object):
    def __init__(self, name, phone, email, change_user_id, change_source):
        self.name = name
        self.phone = phone
        self.email = email
        self.history = []       
        self.history.append(ContactHistory(self, 'created', change_user_id, change_source))

    def update_phone(self, phone, change_user_id, change_source):
        self.phone = phone
        self.history.append(ContactHistory(self, 'phone updated', change_user_id, change_source))

    def get_history(self):
        return self.history

contact = Contact('Bill', '214-555-1212', 'me', 'admin page')
contact.update('972-555-1212', 'me', 'contact management page')
print contact.get_history()

1 个答案:

答案 0 :(得分:1)

这是您使用继承来解决此问题的一种方法。 ChangeableObject可以由任何需要更改的对象继承,该对象只描述用于为历史创建浅层克隆的参数:

from collections import namedtuple

Change = namedtuple("Change", ("old", "new", "action"))

class History(object):
    def __init__(self):
        self.history = []

    def save_change(self, old, new, action):
        change = Change(old, new, action)
        self.history.append(change)

    def get_history(self):
        return self.history

class ChangeableObject(object):
    def __init__(self, make_history=True):
        if make_history:
            self.history = History()
            self.history.save_change(None, self, "created")
        self.cloneable_attributes = ()

    @classmethod
    def get_clone(cls, obj):
        attrs = {attr: getattr(obj, attr) for attr in obj.cloneable_attributes}
        return cls(make_history=False, **attrs)

    def view_history(self):
        return self.history.get_history()

class Contact(ChangeableObject):
    def __init__(self, name, phone, email, make_history=True):
        super(Contact, self).__init__(make_history=make_history)
        self.name = name
        self.phone = phone
        self.email = email
        self.cloneable_attributes = ("name", "phone", "email")

    def update_phone(self, phone):
        clone = self.get_clone(self)
        self.phone = phone
        self.history.save_change(clone, self, "phone updated")

    def __repr__(self):
        return "{} {} {}".format(self.name, self.phone, self.email)

使用示例代码:

c = Contact("me", "123-123-123", "foo@example.com")
c.update_phone("456-456-456")
print c
for i, hist in enumerate(c.view_history()):
    print "{}. {}".format(i, hist)

输出:

me 456-456-456 foo@example.com
0. Change(old=None, new=me 456-456-456 foo@example.com, action='created')
1. Change(old=me 123-123-123 foo@example.com, new=me 456-456-456 foo@example.com, action='phone updated')