我已经创建了这个类,按预期工作,我只想公开一个方法,get_enriched_data
,所以其他的都是非常私有的w/下划线。
功能工作,只是很确信我没有做最python/OOP的方式:
class MergeClients:
def __init__(self,source_df,extra_info_df,type_f):
self.df_all = pd.merge(source_df,extra_info_df, on='clientID', how='left')
self.avg_age = self._get_avg_age()
self.type_f = 'Medium'
def _filter_by_age(self, age):
return self.df_all[self.df_all['Age'] > age]
def _filter_by_family_type(self, f_type):
return self.df_all[self.df_all['familyType'] == f_type]
def _get_avg_age(self):
return self.df_all['Age'].mean()
def get_enriched_data(self):
self.df_all = self._filter_by_age(self.avg_age)
self.df_all=self._filter_by_family_type(self.type_f)
return self.df_all
但是我发现代码看起来很丑,有这么多的自我引用,例如在get_enriched_data
方法每行有三个自我引用,我怎么能纠正这一点?任何关于如何正确使用Python类的指导都是受欢迎的。
编辑:
工作代码示例:
main_df = pd.DataFrame({'clientID':[1,2,3,4,5],
'Name':['Peter','Margaret','Marc','Alice','Maria']})
extra_info = pd.DataFrame({'clientID':[1,2,3,4,5],'Age':[19,35,18,65,57],'familyType':['Big','Medium','Single','Medium','Medium']})
family_stats = MergeClients(main_df,extra_info,'Medium')
family_filtered = family_stats.get_enriched_data()
你的代码有一些奇怪的地方。我要指出一件关于实例的事情:每个方法都可以访问所有属性,所以您并不总是需要将它们作为参数传递:
class MergeClients:
def __init__(self,source_df,extra_info_df,type_f):
self.df_all = pd.merge(source_df,extra_info_df, on='clientID', how='left')
self.avg_age = self._get_avg_age()
self.type_f = 'Medium'
def _filter_by_age(self): #No need for age param
return self.df_all[self.df_all['Age'] > self.avg_age]
def _filter_by_family_type(self): #No need for f_type param
return self.df_all[self.df_all['familyType'] == self.type_f]
def _get_avg_age(self):
return self.df_all['Age'].mean()
def get_enriched_data(self):
self.df_all = self._filter_by_age()
self.df_all = self._filter_by_family_type()
return self.df_all
由于有问题的两个方法:_filter_by_age()
和_filter_by_family_type()
按照约定是私有的,这意味着您的类的客户端不期望调用它们。因此,如果只有这个类的其他方法调用这些方法,并且只有您所显示的那些方法,那么就不需要传递已经是属性的参数。
另一种说法是,对于其他私有方法,有时它们应该使用属性,但在其他时候它们应该接受参数,那么我会让这些方法像你最初那样接受参数。
在Python类中声明的函数可以通过在名称前面加双下划线有效地设置为'private'。例如:
class Clazz():
def __work(self):
print('Working')
def work(self):
self.__work()
c = Clazz()
c.work()
c.__work()
它的输出将是:
工作回溯(最近一次调用):文件"/Volumes/G-DRIVE Thunderbolt 3/PythonStuff/play.py",第575行c = z()AttributeError: ' zz'对象没有属性'__work'
换句话说,__work函数已经被"隐藏"了