问题描述
我使用抽象类及其子类实现了如下设计
from abc import ABC,abstractmethod
class Pipeline(ABC):
@abstractmethod
def read_data(self):
pass
def __init__(self,**kwargs):
self.raw_data = self.read_data()
self.process_data = self.raw_data[self.used_cols]
class case1(Pipeline):
def read_data(self):
return pd.read_csv("file location") # just hard coding for the file location
@property
def used_cols(self):
return ['col_1','col_2','col_3','col_4']
我可以调用 case1
的类如下。它实际上会将 csv 文件读入 Pandas 数据帧。
data = case1()
这个现有的设计将返回四个硬编码列,例如,'col_1'、'col_2'、'col_3' 和 'col_4',它工作正常。目前我想通过修改子类来控制要返回的列,具体是used_cols
的函数。我修改了类 case1
如下,但会导致错误信息。
class case1(Pipeline):
def read_data(self):
return pd.read_csv("file location") # just hard coding for the file location
@property
def used_cols(self,selected_cols):
return selectd_cols
它被调用如下
selected_cols = ['col_2','col_3']
data = case1(selected_cols)
原来这个修改是不对的,并产生了错误信息如 TypeError: init_subclass() 不接受关键字参数所以我的问题是如何修改子类以获得所需的控制。
解决方法
参考
我认为您没有完全理解属性的用途。
如果您创建一个属性 used_cols,您将使用 obj.used_cols 而不是 obj.used_cols() 访问它。创建属性后,直接调用底层函数并不容易。
csv 文件:
col_0,col_1,col_2,col_3
1,1,2
2,3,4
3,6
代码:
from abc import ABC,abstractmethod
import pandas as pd
class Pipeline(ABC):
@abstractmethod
def read_data(self):
pass
def __init__(self,**kwargs):
self.raw_data = self.read_data()
self.used_cols = kwargs["selected_cols"]
self.process_data = self.raw_data[self.used_cols]
class case1(Pipeline):
def read_data(self):
return pd.read_csv("file_location.csv") # just hard coding for the file location
@property
def used_cols(self):
return self._used_cols
@used_cols.setter
def used_cols(self,selected_cols):
self._used_cols = selected_cols
selected_cols = ['col_2','col_3']
data = case1(selected_cols = selected_cols)
print(data.process_data)
结果:
col_2 col_3
0 1 2
1 3 4
2 3 6