2013-02-21 85 views
0

我試圖從封裝類有一個封裝類抓取上下文,就像一個標籤。其中一種方法就是在實例化過程中傳遞標籤,如下所示。如何在Python中封裝類中訪問上下文標籤?

我見過的記錄模塊如何讓你訂閱與get_logger功能sublogs,我想有一個GET_CONTEXT()函數。有沒有辦法做到這一點?

如果這個標籤的傳遞走到了一個層次,就像下面的YetAnotherClass一樣,它似乎是可以忍受的......但是如果你必須把它傳遞給3或4個關卡---這就是我真正想要另一個解決方案通過這個標籤的地方周圍。

我應該以不同的方式思考這個?下面是一些示例代碼:

class RootClass(object) : 
    def __init__(self) : 
     self.ac = AnotherClass('root_class_context') 
    def do_insert(self) : 
     """ use DataTableMgr class to update table """ 
     self.ac.insert_to_table('field1', 'field2', 'field3') 

class AnotherClass(object) : 
    def __init__(self, label) : 
     self.context = label 
     self.dtm = DataTableMgr('arg1','arg2', 'arg3', 'arg4', self.context) 

    def insert_to_table(self, field1, field2, field3) : 
     """ insert args to database using DataTableMgr """ 
     self.dtm.insert_to_table(field1, field2, field3) 


class YetAnotherClass(object) : 
    def __init__(self) : 
     self.dtm = DataTableMgr('arg1','arg2', 'arg3', 'arg4', 'yetanother_context') 

    def do_insert(self) : 
     """ use DataTableMgr class to update table """ 
     self.dtm.insert_to_table('field1', 'field2', 'field3') 

class DataTableMgr(object) : 
    """ manage insert, updates to some table """ 
    def __init__(self, arg1, arg2, arg3, arg4, user_id) : 
     self.context = user_id 

    def insert_to_table(self, field1, field2, field3) : 
     """ insert fields to table, while updating user id""" 
     print("inserting...(pretending to be updating sql database)") 
     print(field1, field2, field3, self.context) 
     print 

if __name__ == "__main__" : 
    #instantiate a class once removed from the inserting class and do insert 
    rc = RootClass() 
    rc.do_insert() 

    #instantiate a class directly accessing the class for inserting 
    yac = YetAnotherClass() 
    yac.do_insert()    

    #note how the context changes  
    print         
    print("Notice how the context changes? " 
     ".. is there a better way to pass around this context information?") 
+0

這裏的另一個想法,可能是使用環境變量...在基類中做到這一點:'進口操作系統; os.environ.setdefault('context','mylabel')'然後是'os.environ.get('context')'在模塊中。 – Voortuck 2013-02-21 22:47:06

回答

0

嗯,我能想到的simpliest方式使用繼承:

class DataTableMgr(object): 
    """ manage insert, updates to some table """ 
    def __init__(self, arg1, arg2, arg3, arg4, context): 
     self.context = context 

    def insert_to_table(self, field1, field2, field3): 
     """ insert fields to table, while updating user id""" 
     print("inserting...(pretending to be updating sql database)") 
     print(field1, field2, field3, self.context) 
     print 

    def do_insert(self): 
     """ use DataTableMgr class to update table """ 
     self.insert_to_table('field1', 'field2', 'field3') 


class AnotherClass(DataTableMgr): 
    def __init__(self, context): 
     DataTableMgr.__init__(self, 'arg1', 'arg2', 'arg3', 'arg4', context) 


class RootClass(AnotherClass): 
    def __init__(self): 
     AnotherClass.__init__(self, 'root_class_context') 


class YetAnotherClass(DataTableMgr): 
    def __init__(self): 
     DataTableMgr.__init__(
      self, 'arg1', 'arg2', 'arg3', 'arg4', 'yetanother_context') 

但是,也許你不想使用繼承,因爲RootClass是不是DataTableMgr,而是DataTableMgr。 在這種情況下,您可能會考慮使用多態性將上下文傳遞給委託封裝對象。

class Base(object): 
    def do_insert(self): 
     """ use DataTableMgr class to update table """ 
     self.dtm.insert_to_table('field1', 'field2', 'field3', self.context) 

    def insert_to_table(self, field1, field2, field3, context): 
     """ insert args to database using DataTableMgr """ 
     self.dtm.insert_to_table(field1, field2, field3, context) 

爲了方便多態性,受委託的對象應該是與self.dtm訪問。因此,調用do_insert時,委託對象self.dtm將調用其方法insert_to_table。如果self.dtmDataTableMgr實例,則調用DataTableMgr.insert_to_table。但是,如果self.dtm是另一個Base實例,那麼委託的insert_to_table方法被調用。等等,等等,直到代表是DataTableMgr

這裏是一個可運行的代碼示例:

class Base(object): 
    def do_insert(self): 
     """ use DataTableMgr class to update table """ 
     self.dtm.insert_to_table('field1', 'field2', 'field3', self.context) 

    def insert_to_table(self, field1, field2, field3, context): 
     """ insert args to database using DataTableMgr """ 
     self.dtm.insert_to_table(field1, field2, field3, context) 


class RootClass(Base): 
    def __init__(self): 
     self.context = 'root_class_context' 
     self.dtm = AnotherClass() 


class AnotherClass(Base): 
    def __init__(self): 
     self.dtm = DataTableMgr('arg1', 'arg2', 'arg3', 'arg4') 


class YetAnotherClass(Base): 
    def __init__(self): 
     self.context = 'yetanother_context' 
     self.dtm = DataTableMgr('arg1', 'arg2', 'arg3', 'arg4') 


class DataTableMgr(object): 
    """ manage insert, updates to some table """ 
    def __init__(self, arg1, arg2, arg3, arg4): 
     pass 

    def insert_to_table(self, field1, field2, field3, context): 
     """ insert fields to table, while updating user id""" 
     print("inserting...(pretending to be updating sql database)") 
     print(field1, field2, field3, context) 
     print 

if __name__ == "__main__": 
    # instantiate a class once removed from the inserting class and do insert 
    rc = RootClass() 
    rc.do_insert() 

    # instantiate a class directly accessing the class for inserting 
    yac = YetAnotherClass() 
    yac.do_insert() 

    # note how the context changes 
    print 
    print("Notice how the context changes? " 
      ".. is there a better way to pass around this context information?") 
+0

這是一個很好的多態性提醒。就我而言,我正在處理一堆遺留代碼,這種重寫對於這種變更很費力。 – Voortuck 2013-02-21 22:46:13