python - 如何动态地知道和实例化在 Python 模块中实现的一个类
问题描述
假设在“./data_writers/excel_data_writer.py”中,我有:
from generic_data_writer import GenericDataWriter
class ExcelDataWriter(GenericDataWriter):
def __init__(self, config):
super().__init__(config)
self.sheet_name = config.get('sheetname')
def write_data(self, pandas_dataframe):
pandas_dataframe.to_excel(
self.get_output_file_path_and_name(), # implemented in GenericDataWriter
sheet_name=self.sheet_name,
index=self.index)
在“./data_writers/csv_data_writer.py”中,我有:
from generic_data_writer import GenericDataWriter
class CSVDataWriter(GenericDataWriter):
def __init__(self, config):
super().__init__(config)
self.delimiter = config.get('delimiter')
self.encoding = config.get('encoding')
def write_data(self, pandas_dataframe):
pandas_dataframe.to_csv(
self.get_output_file_path_and_name(), # implemented in GenericDataWriter
sep=self.delimiter,
encoding=self.encoding,
index=self.index)
在“./datawriters/generic_data_writer.py”中,我有:
import os
class GenericDataWriter:
def __init__(self, config):
self.output_folder = config.get('output_folder')
self.output_file_name = config.get('output_file')
self.output_file_path_and_name = os.path.join(self.output_folder, self.output_file_name)
self.index = config.get('include_index') # whether to include index column from Pandas' dataframe in the output file
假设我有一个 JSON 配置文件,其中包含如下键值对:
{
"__comment__": "Here, user can provide the path and python file name of the custom data writer module she wants to use."
"custom_data_writer_module": "./data_writers/excel_data_writer.py"
"there_are_more_key_value_pairs_in_this_JSON_config_file": "for other input parameters"
}
在“main.py”中,我想根据custom_data_writer_module
上面的 JSON 配置文件中提供的数据导入模块。所以我写了这个:
import os
import importlib
def main():
# Do other things to read and process data
data_writer_class_file = config.get('custom_data_writer_module')
data_writer_module = importlib.import_module\
(os.path.splitext(os.path.split(data_writer_class_file)[1])[0])
dw = data_writer_module.what_should_this_be? # <=== Here, what should I do to instantiate the right specific data writer (Excel or CSV) class instance?
for df in dataframes_to_write_to_output_file:
dw.write_data(df)
if __name__ == "__main__":
main()
正如我在上面的代码中所问的那样,我想知道是否有一种方法可以检索和实例化 Python 模块中定义的类,假设模块中只定义了一个类。或者,如果有更好的方法来重构我的代码(使用某种模式)而不改变上述 JSON 配置文件的结构,我想向 StackOverflow 上的 Python 专家学习。提前感谢您的建议!
解决方案
您可以通过以下方式轻松做到这一点vars
:
cls1,=[v for k,v in vars(data_writer_module).items()
if isinstance(v,type)]
dw=cls1(config)
逗号强制只找到一个类。如果允许模块执行类似from collections import deque
(或什至foo=str
)的任何操作,您可能需要基于v.__module__
.
推荐阅读
- c# - c#中两个列表交叉连接后将数据合并到单个字典中
- angular - 如何将必填字段添加到 mat-button-toggle-group 数组?
- java - 编写一个 while 循环,打印所有可被 10 整除且小于给定数 n 的正数
- node.js - 如何更新 mongodb 中的对象数组?
- swift - 处理涉及移动/动画 UiViews
- javascript - 在 .env.development 和 .env.example 中,哪一个 nodemon 默认使用?
- php - 消息:试图获取非对象的属性“id”
- javascript - 为什么没有加载属性
- flutter - 如何在颤振中创建以下形状?
- visual-studio-code - 使用 vscode-remote ssh 时跨设备使用相同的终端会话