Организация классов и экземпляров в 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)