Организация классов и экземпляров в python3

У меня есть класс, который хранит dataframe (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

Проблема этого подхода заключается в том, что я хочу получить доступ к исходным предварительно отфильтрованным df и отфильтрованным df после выполнения фильтрации с помощью метода filter_ref(). Однако это невозможно сделать с помощью приведенного выше кода. Я изменил класс, как показано ниже, чтобы к исходному 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

В приведенном выше примере я могу получить доступ к отфильтрованному df и оригинальному df в классе File, и я разделила методы фильтрации и выбора данных. Теперь проблема в том, что я не могу использовать методы File, view_ref(), с экземпляром self.filter.

Мне трудно определить, как лучше всего организовать этот код. Может ли кто-нибудь помочь направить меня в наиболее питоническом направлении, чтобы организовать это?

1 ответ

Не существует единого решения для всех ситуаций, которые вы могли бы иметь.

Вы можете использовать неизменный File объект для доступа к вашим данным, и любые функции, которые изменяют ваши данные, будут создавать новый объект с новыми данными. Это полезно, когда отфильтрованные и исходные данные имеют одинаковые свойства или, по крайней мере, мы знаем, какой класс мы должны создать после фильтрации. Хорошие примеры этой стратегии - цифры (int, float, Decimal) и строковые объекты (str, bytes).

Пример класса для этого решения вы можете увидеть ниже. Я использовал здесь 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)
Другие вопросы по тегам