TypeError: __init_subclass__() takes no keyword arguments related to subclass and abstract class design

TypeError: __init_subclass__() takes no keyword arguments related to subclass and abstract class design

我使用抽象 class 及其子class class 实现了如下设计

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 的 class,如下所示。它实际上会将 csv 文件读入 pandas 数据帧。

data = case1()

此现有设计将 return 四个硬编码列,例如 'col_1'、'col_2'、'col_3' 和 'col_4',而且效果很好.目前想通过修改subclass来控制要return的列,具体就是used_cols的功能。我修改了classcase1如下,但是会报错

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() 没有关键字参数所以我的问题是如何修改 subclass 以获得所需的控件。

参考

  • Python: How to pass more than one argument to the property getter?

I think you did not fully understand the purpose of properties.

If you create a property used_cols, you'll accessing it using obj.used_cols instead of obj.used_cols(). After creating the property it's not easily possible to call the underlying function directly.

csv 文件:

col_0,col_1,col_2,col_3
1,1,1,2
2,3,3,4
3,3,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