如何动态地知道和实例化在 Python 模块中实现的一个 class
How to know and instantiate only one class implemented in a Python module dynamically
假设在“./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"中,我想根据上面JSON配置文件中提供的custom_data_writer_module
导入数据写入模块。所以我写了这个:
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 模块中定义的 class 假设只有一个 class 在模块中定义。或者,如果有更好的方法来重构我的代码(使用某种模式)而不更改上述 JSON 配置文件的结构,我想向 Whosebug 上的 Python 专家学习。预先感谢您的建议!
您可以使用 vars
轻松做到这一点:
cls1,=[v for k,v in vars(data_writer_module).items()
if isinstance(v,type)]
dw=cls1(config)
逗号强制找到一个 class。如果允许模块执行 from collections import deque
(甚至 foo=str
)之类的操作,您可能需要根据 v.__module__
.
进行过滤
假设在“./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"中,我想根据上面JSON配置文件中提供的custom_data_writer_module
导入数据写入模块。所以我写了这个:
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 模块中定义的 class 假设只有一个 class 在模块中定义。或者,如果有更好的方法来重构我的代码(使用某种模式)而不更改上述 JSON 配置文件的结构,我想向 Whosebug 上的 Python 专家学习。预先感谢您的建议!
您可以使用 vars
轻松做到这一点:
cls1,=[v for k,v in vars(data_writer_module).items()
if isinstance(v,type)]
dw=cls1(config)
逗号强制找到一个 class。如果允许模块执行 from collections import deque
(甚至 foo=str
)之类的操作,您可能需要根据 v.__module__
.