2010-11-18 49 views
1

我使用的是Python 3,但问题并没有真正与特定语言绑定。实现子表(查看表):设计类关系

我有class Table实现一个主键的表。该类的一个实例包含实际的数据(这是非常大的)。

我想允许用户通过为表的行提供一个过滤器来创建一个子表。我不想复制表格,所以我打算在子表格中保留父表格中主键的子集。

显然,子表只是父表的视图;如果父表发生更改,它将会改变,如果父表被销毁,它将变为无效,并且如果它们从父表中删除,它将丢失一些行。 [编辑:澄清,如果父表被改变,我不在乎子表发生了什么;任何行为都可以。]

我该如何连接两个类?我在想:

class Subtable(Table): 
    def __init__(self, table, filter_function): 
    # ... 

我的假设是,Subtable保持的Table的接口,除了略微覆盖继承方法只是为了检查,如果该行是这是一个很好的实现?

问题是,我不知道如何初始化Subtable实例,因为我不想复制传递给它的表对象。它甚至有可能吗?

此外,我想给class Table一个实例方法,返回Subtable实例;但是在Subtable上创建了Table的依赖关系,我想最好避免这种情况?

+0

你有没有考虑过把这个数据结构转移到数据库中? Python自带'sqlite3',它可以让你在内存中创建SQL DB。 – katrielalex 2010-11-18 20:16:19

+0

是的,但现在决定坚持自定义实现。 – max 2010-11-18 20:17:56

回答

1

我将使用以下(我省略了很多方法,如排序,在这种安排工作得非常好,也省略了错误处理):

class Table: 
    def __init__(self, *columns, pkey = None): 
     self.pkey = pkey 
     self.__columns = columns 
     self.__data = {} 

    def __contains__(self, key): 
     return key in self.__data 

    def __iter__(self): 
     for key in self.__order: 
      yield key 

    def __len__(self): 
     return len(self.__data) 

    def items(self): 
     for key in self.__order: 
      yield key, self.__data[key] 

    def insert(self, *unnamed, **named): 
     if len(unnamed) > 0: 
      row_dict = {} 
      for column_id, column in enumerate(self.__columns): 
       row_dict[column] = unnamed[column_id] 
     else: 
      row_dict = named 
     key = row_dict[self.pkey] 
     self.__data[key] = row_dict 

class Subtable(Table): 
    def __init__(self, table, row_filter): 
     self.__order = [] 
     self.__data = {} 
     for key, row in table.items(): 
      if row_filter(row): 
       self.__data[key] = row 

本质上讲,我复制主键,并创建与其绑定的数据的引用。如果父表中的行被销毁,它仍然存在于子表中。如果在父表中修改了一行,它也在子表中修改。这很好,因为我的要求是“当父表被修改时发生任何事情”。

如果您发现本设计有任何问题,请告诉我。