python3中的类和实例组织

时间:2017-04-09 14:19:30

标签: python python-3.x class oop organization

我有一个存储数据帧(df)的类,并包含允许过滤所述df的方法:

class File(object):

    def __init__(self, f):
        self.f = f

    def view_ref(self):
        return self.f['REF']

    def filter_ref(self, val):
        ''' Filter REF column for the given val
        '''
        f = self.f[self.f['REF'] == val]
        self.f = f
        return self.f

这种方法的问题是我希望能够在使用filter_ref()方法执行过滤后访问原始的预过滤df和过滤后的df。但是,这不能用上面的代码完成。我改变了下面的类,所以可以随时访问原始的df:

class File(object):

    def __init__(self, f):
        self.f = f
        self.filtered = None

    def view_ref(self):
        return self.f['REF']

    def filter_ref(self, val):
        ''' Filter REF column for the given val
        '''
        filtered = self.f[self.f['REF'] == val]
        self.filtered = filtered
        return self.filtered

上述方法的问题是我最终会有各种方法来过滤和选择数据,我想将它们分开。所以我尝试为每个目的创建两个不同的类:

class File(object):

    def __init__(self, f):
        self.f = f
        self.filter = FilterFile(f)

    def view_ref(self):
        return self.f['REF']

class FilterFile(object):

    def __init__(self, f):
        self.f = f

    def filtered_ref(self, val):
        f = self.f[self.f['REF'] == val]
        self.f = f
        return self.f

在上面的示例中,我可以访问File类中已过滤的df和原始df,并且我保留了过滤和选择数据的方法。现在的问题是我不能将文件方法view_ref()与self.filter实例一起使用。

我很难确定如何最好地组织此代码。有人可以帮助我指出最狡猾的方向来组织这个吗?

1 个答案:

答案 0 :(得分:0)

对于您可能拥有的所有情况,没有单一的解决方案。

您可以使用不可变File对象来访问您的数据,任何修改数据的函数都会生成包含新数据的新对象。当过滤的原始数据具有相同的属性或者至少我们知道过滤后应该生成哪个类时,这很有用。此策略的好例子是数字(intfloatDecimal)和类似字符串的对象(strbytes)。

此解决方案的示例类,您可以在下面看到。我在这里使用filter_function作为参数来提供更多的运行时灵活性:

class File:
   def __init__(self, df, filter_function=None):
       self.df = df
       self.filter_function = filter_function

   def view_field(self, field):
       return self.df[field]

   def filter(self, *args, filter_function=None):
       """ Returns filtered data in new File object. """

       if not self.filter_function:
            return self
       filtered = self.filter_function(self.df, *args)  # filter our data
       return File(filtered, filter_function)