首页 > 解决方案 > 使用类来组织共享输入的功能是否合适?

问题描述

为了提供一些背景信息,我正在构建一个从各种不同来源提取数据的风险模型。最初,我将模型编写为单个函数,在执行时将不同的数据源作为 pandas.DataFrame 对象读取,并在必要时使用这些对象。随着模型变得越来越复杂,它很快变得不可读,我发现自己经常复制粘贴代码块。

为了清理代码,我决定创建一个在初始化时读取、清理和解析数据的类。初始化需要大约一分钟的时间来运行并完整地构建我的模型。

该类还具有一些附加功能。有一个 generate_email 方法可以发送一封电子邮件,其中包含有关高风险因素的详细信息,另一个方法 append_history 可以为风险模型设置时间点并将其保存,以便我可以运行时间比较。

关于这两种附加方法的问题是,我无法想象在没有首先重新校准我的风险模型的情况下我会调用它们的情况。所以我考虑像我的其他方法一样在init () 中调用它们。我之所以没有这样做,不仅是因为我一开始就试图证明上课是合理的。

我正在咨询这个社区,因为我的项目结构感觉笨重和尴尬。我倾向于相信我根本不应该使用课程。仅仅为了组织的目的而创建课程是否令人不悦?此外,在init ()中调用实例方法(运行时间超过一分钟)是不好的做法吗?

最终,我正在寻找保证或更好的代码结构。任何帮助将不胜感激。

这是一些显示我的项目结构的伪代码:

class RiskModel:
    def __init__(self, data_path_a, data_path_b):
        self.data_path_a = data_path_a
        self.data_path_b = data_path_b

        self.historical_data = None
        self.raw_data = None
        self.lookup_table = None
        self._read_in_data()

        self.risk_breakdown = None
        self._generate_risk_breakdown()

        self.risk_summary = None
        self.generate_risk_summary()

    def _read_in_data(self):
        # read in a .csv
        self.historical_data = pd.read_csv(self.data_path_a)

        # read an excel file containing many sheets into an ordered dictionary
        self.raw_data = pd.read_excel(self.data_path_b, sheet_name=None)


        # store a specific sheet from the excel file that is used by most of
        # my class's methods
        self.lookup_table = self.raw_data["Lookup"]

    def _generate_risk_breakdown(self):
        '''
        A function that creates a DataFrame from self.historical_data,
        self.raw_data, and self.lookup_table and stores it in 
        self.risk_breakdown
        '''
        self.risk_breakdown = some_dataframe

    def _generate_risk_summary(self):
        '''
        A function that creates a DataFrame from self.lookup_table and 
        self.risk_breakdown and stores it in self.risk_summary
        '''
        self.risk_summary = some_dataframe

    def generate_email(self, recipient):
        '''
        A function that sends an email with details about high risk factors
        '''

if __name__ == "__main__":
    risk_model = RiskModel(data_path_a, data_path_b)
    risk_model.generate_email(recipient@generic.com)

标签: pythonpandasclassoop

解决方案


在我看来,这是组织项目的好方法,尤其是因为您提到了部分代码的高可重用率。

不过有一件事,我不会把_read_in_data,_generate_risk_breakdown_generate_risk_summary方法放在里面__init__,而是让用户在初始化RiskModel类实例后调用这个方法。

这样,用户将能够从不同的路径读取数据,或者只生成风险分解或摘要,而无需再次读取数据。

像这样的东西:

my_risk_model = RiskModel()
my_risk_model.read_in_data(path_a, path_b)
my_risk_model.generate_risk_breakdown(parameters)
my_risk_model.generate_risk_summary(other_parameters)

generate_risk_breakdown如果用户以破坏逻辑链的顺序调用这些方法的问题,则可以在 if或被generate_risk_summary调用 before时抛出异常read_in_data。当然,您只能将generate...方法移出,将数据导入留在内部__init__

为了提倡更多地公开这些generate...方法__init__,请考虑一个案例场景,您希望在其中生成多个风险摘要,并更改各种参数。有意义的是,不要RiskModel每次都创建并读取相同的数据,而是将输入更改为generate_risk_summary方法:

my_risk_model = RiskModel()
my_risk_model.read_in_data(path_a, path_b)

for parameter in [50, 60, 80]:
    my_risk_model.generate_risk_summary(parameter)
    my_risk_model.generate_email('test@gmail.com')

推荐阅读