跨模块调用仅接收self的方法,如何传递自定义实例参数?
你当前报错的核心原因是模块B中创建的collection = Transaction()实例未正确初始化path,且该实例的input_1/input_2/input_3始终为None,调用merge_input_data()时pd.concat接收到的全是None对象,因此抛出错误。
你的需求是复用模块A中merge_input_data()的合并逻辑,但不想显式传递input_1/input_2/input_3这三个参数,而是直接使用模块B实例自身的对应属性。以下是几种可行方案:
方案1:重构模块A的合并方法(推荐)
直接修改模块A的merge_input_data,让它支持接收外部传入的DataFrame列表,同时保留原有逻辑的兼容性:
# 模块A 修改后的merge_input_data def merge_input_data(self, data_frames=None): # 如果没有传入外部数据,就用自身实例的属性 if data_frames is None: data_frames = [self.input_1, self.input_2, self.input_3] self.input_merged = pd.concat(data_frames) return self.input_merged
然后在模块B中调用时,直接传入自身的属性列表:
# 模块B 的test_merge_input_data方法 def test_merge_input_data(self): # 用当前B实例的input数据调用A的合并方法 merged = collection.merge_input_data([self.input_1, self.input_2, self.input_3]) self.input_merged = merged
这种方式既保留了A原有逻辑的使用方式,又灵活支持外部数据传入,且不需要显式逐个列参数(用列表打包即可)。
方案2:动态赋值属性给A的实例(无需修改A)
如果不想修改模块A的代码,可以将模块B实例的input_1/input_2/input_3动态赋值给A的实例,再调用方法:
# 模块B 的test_merge_input_data方法 def test_merge_input_data(self): # 遍历需要传递的属性名,批量赋值给A的实例 for attr in ['input_1', 'input_2', 'input_3']: setattr(collection, attr, getattr(self, attr)) # 调用A的合并方法 self.input_merged = collection.merge_input_data()
这里通过setattr和getattr批量处理属性,避免了逐个显式赋值,达到了你“无需显式列出所有待传参数”的需求。注意:要确保模块B中创建collection实例时正确传入path(虽然这里合并逻辑不需要path,但初始化时需要),比如改成collection = Transaction(self.path)。
方案3:让模块B的类继承模块A的Transaction类
如果模块B的TestTransaction本身就是对Transaction的测试扩展,直接继承可以更自然地复用方法:
# 模块B 修改后的代码 from A import Transaction class TestTransaction(Transaction): # 继承Transaction def __init__(self, path): super().__init__(path) # 调用父类初始化 self.input_1 = None self.input_2 = None self.input_3 = None self.input_merged = None self.output = None def import_test_input_data(self): # 原有读取测试数据的逻辑不变 self.input_1 = pd.read_excel(...) self.input_2 = pd.read_excel(...) self.input_3 = pd.read_excel(...) return self.input_1, self.input_2, self.input_3 def test_merge_input_data(self): # 直接调用父类的merge_input_data,自动使用当前实例的input属性 self.input_merged = self.merge_input_data()
这种方式完全不需要额外传参,因为继承后TestTransaction实例本身就拥有merge_input_data方法,直接调用即可使用自身的input_1/2/3属性。
内容的提问来源于stack exchange,提问作者29nivek

