python - 使用类来组织共享输入的功能是否合适?
问题描述
为了提供一些背景信息,我正在构建一个从各种不同来源提取数据的风险模型。最初,我将模型编写为单个函数,在执行时将不同的数据源作为 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)
解决方案
在我看来,这是组织项目的好方法,尤其是因为您提到了部分代码的高可重用率。
不过有一件事,我不会把_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')
推荐阅读
- python - 如果两个列是相同的 Pandas,则在它们之间添加列
- scrapy - XPath 选择器返回空列表
- visual-studio-2019 - Visual Studio 2019 - Angular 9.1.9 - 没有实时重新加载
- javascript - google fitBounds 无法按预期工作
- google-cloud-dataflow - 状态和输出的原子性
- android - Kotlin 1.4 是否放弃对 Coroutine Actors 的支持
- python - python中隔离林是否必须设置污染值?
- python - 导入 python 模块时没有这样的文件或目录。文件肯定存在于同一路径中
- laravel - 使用两个数据透视表在 laravel 中获取多对多关系的数据
- console - 如何在 Google 控制台上将包名称更改为小写?