使用pythonfmu生成FMU时__init__方法的参数错误问题
问题分析与解决方案
核心错误原因
Fmi2Slave构造函数参数错误:Fmi2Slave的初始化仅接受关键字参数,且必须传入instance_name,你之前错误地传入了Application实例,且未提供必填的instance_name。- FMU构建时机逻辑错误:你在
__init__中直接执行构建命令,但此时选中的节点还未传入,生成的FMU不会包含目标变量;同时手动调用self.__init__()是不符合Python实例初始化规范的错误操作。 - 架构设计偏差:
pythonfmu的FMU构建依赖静态的Slave类定义,无法在运行时动态给实例添加变量,必须提前生成包含目标变量的类脚本再执行构建。
修正后的代码实现
重构FmuGenerator类(不再继承Fmi2Slave)
from pythonfmu import Fmi2Causality, Fmi2Variability, Integer import subprocess import tempfile import os class FmuGenerator: def __init__(self): self.author = "Till" self.description = "A Test FMU" def generate_fmu(self, selected_nodes): # 动态生成包含选中节点的FMU Slave类代码 slave_code = f""" from pythonfmu import Fmi2Causality, Fmi2Variability, Fmi2Slave, Integer class OPCSlave(Fmi2Slave): author = "{self.author}" description = "{self.description}" def __init__(self, instance_name): super().__init__(instance_name) """ # 为每个选中节点注册FMU输入变量 for node in selected_nodes: slave_code += f""" self.register_variable(Integer("{node}", variability=Fmi2Variability.continuous, causality=Fmi2Causality.input, start=0.0)) """ # 添加FMU必需的do_step方法 slave_code += """ def do_step(self, current_time, step_size): return True """ # 创建临时脚本文件保存生成的Slave类 with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: temp_script_path = f.name f.write(slave_code) try: # 执行FMU构建命令 subprocess.run(["pythonfmu", "build", "-f", temp_script_path, "VSCode"], check=True) print(f"FMU生成成功,输出路径: {os.path.splitext(temp_script_path)[0]}.fmu") finally: # 清理临时脚本文件 os.unlink(temp_script_path)
修改Application类的节点选中回调
def on_nodes_selected(self, selected_nodes): self.fmu_generator = FmuGenerator() self.fmu_generator.generate_fmu(selected_nodes)
关键修正说明
- 动态生成Slave脚本:根据选中的节点动态生成包含对应输入变量的Slave类代码,确保构建FMU时变量已正确定义。
- 正确调用构建命令:在获取到选中节点后再执行构建,避免空变量FMU的生成。
- 避免错误初始化操作:移除手动调用
__init__()的逻辑,遵循Python实例初始化规范。 - 清理临时文件:使用临时文件保存动态生成的脚本,构建完成后自动清理,避免冗余文件。
内容的提问来源于stack exchange,提问作者till12mann
相关产品推荐
相关产品推荐

