父类无法访问子类文件局部变量的报错及解决方法求助
问题分析与解决
问题场景
transfer_function.py 代码
from abc import ABC import sympy class TransferFunction(ABC): def __init__(self, tf): self.__domain = 's' self.__F = tf self.__f = sympy.inverse_laplace_transform(tf, s, t, noconds=True) self.__tf = tf
controller.py 代码
import sympy from transfer_function import TransferFunction # 假设IController为已定义的接口类 class ProportionalController(IController, TransferFunction): def __init__(self, param): self._param = param super().__init__(param) def __repr__(self): return f'{self.__class__.__name__} ({self._param})' if __name__ == '__main__': t, s = sympy.symbols('t, s') controller = ProportionalController(5) print(controller)
报错信息
Traceback (most recent call last): File "E:\Code\python_files\Controller-Simulation\controller.py", line 70, in <module> controller = ProportionalController(5) File "E:\Code\python_files\Controller-Simulation\controller.py", line 28, in __init__ super().__init__(param) File "E:\Code\python_files\Controller-Simulation\transfer_function.py", line 10, in __init__ self.__f = sympy.inverse_laplace_transform(tf, s, t, noconds=True) NameError: name 's' is not defined Process finished with exit code 1
疑问:将TransferFunction类直接复制到controller.py中程序可正常运行,为何通过导入文件的方式会报错?该如何解决?
原因分析
Python中每个模块都是独立的命名空间,transfer_function.py无法直接访问controller.py中定义的变量s和t。哪怕你在主模块里定义了这两个符号,子模块也看不到它们的存在。
当你把TransferFunction类复制到controller.py时,s和t与类处于同一个命名空间,代码能正常找到这两个变量,因此不会报错。
解决方案
方案一:在transfer_function.py内定义所需符号
修改transfer_function.py,在模块内部提前定义拉普拉斯变换所需的符号:
from abc import ABC import sympy # 在模块内定义符号,确保类可以访问 t, s = sympy.symbols('t, s') class TransferFunction(ABC): def __init__(self, tf): self.__domain = 's' self.__F = tf self.__f = sympy.inverse_laplace_transform(tf, s, t, noconds=True) self.__tf = tf
方案二:将符号作为参数传入构造函数
修改TransferFunction的构造方法,让调用者主动传入符号,消除对外部命名空间的依赖:
# transfer_function.py from abc import ABC import sympy class TransferFunction(ABC): def __init__(self, tf, s, t): self.__domain = 's' self.__F = tf self.__f = sympy.inverse_laplace_transform(tf, s, t, noconds=True) self.__tf = tf
同时修改controller.py的调用逻辑:
# controller.py import sympy from transfer_function import TransferFunction class ProportionalController(IController, TransferFunction): def __init__(self, param, s, t): self._param = param super().__init__(param, s, t) def __repr__(self): return f'{self.__class__.__name__} ({self._param})' if __name__ == '__main__': t, s = sympy.symbols('t, s') controller = ProportionalController(5, s, t) print(controller)
内容的提问来源于stack exchange,提问作者K.XGai
相关产品推荐
相关产品推荐

