2016-04-28 9 views
2

私は変更履歴を追跡したいいくつかのクラス(連絡先など)を持っています。以下は私の出発点です。これは一般的な使用例だと思いますので、ここではベストプラクティスに関するガイダンスを参考にしてください。これは複数の継承を使用するのに適していますか?その外観はどうですか?「オブジェクト履歴」のPython継承のベストプラクティス

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

おそらくhttp://stackoverflow.com/questions/8858525/track-changes-to-lists-and-dictionaries-in-pythonが重要です。 – larsks

+0

@larsks ... @JackOfAllこのリンクには良いことがありますが、おそらくあなたは 'メモパターン 'を見たいと思っていますか?あなたが望むものは直接ではありませんが、そこから新しいアイデアを得るでしょうか? –

答えて

1

これには、継承を使用する方法があります。サンプルコードでは

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) 

ChangeableObjectは、そのオブジェクトがちょうど歴史のためのシャローコピーを作成するために使用されるパラメータを記述して、変更可能に必要なすべてのオブジェクトによって継承することができ

c = Contact("me", "123-123-123", "[email protected]") 
c.update_phone("456-456-456") 
print c 
for i, hist in enumerate(c.view_history()): 
    print "{}. {}".format(i, hist) 

出力:

me 456-456-456 [email protected] 
0. Change(old=None, new=me 456-456-456 [email protected], action='created') 
1. Change(old=me 123-123-123 [email protected], new=me 456-456-456 [email protected], action='phone updated') 
+0

ありがとう!それはとても役に立ちます。 – JackOfAll

関連する問題