如何在Python中复用已初始化的OM类实例避免重复调用?
我有一个包含OM类的OM脚本,还有Config脚本以及作为启动脚本的VTE脚本。当前OM类会被初始化两次(打印两次'Initialized'),我希望在Config中直接复用VTE中已创建的OM实例,而非重新调用初始化。我通过在OM类中定义类变量OM_Handler存储实例实现了需求,但听闻全局类变量口碑不佳,想请教该方案是否最优,有无更好的实现方式。
原代码
OM类原代码
class OM: def __init__( Self , Debug_Mode = False ): print( "Initialized" ) Self.Debug_Mode = Debug_Mode Self.Registered_Modules = { }
Config类原代码
class Config: def __init__( Self ) : OM = __import__( 'OM' ) Self.OM = OM.OM.Load_Module( ) print( Self.OM ) Self.Config_Entries = { }
VTE类代码
class VTE: def __init__( Self ) : Self.OM = OM( Debug_Mode = False ) CFG = Self.OM.Load_Module( 'Config' ) CFG.Config_Loader( )
我的实现代码
修改后的OM类
class OM : OM_Handler = "None" def __init__( Self , Debug_Mode = False ) : OM.OM_Handler = Self Self.Debug_Mode = Debug_Mode Self.Registered_Modules = { }
修改后的Config类
class Config( ) : def __init__( Self ) : Self.Config_Entries = { } OM = __import__( 'OM' ) OM_Handler = OM.OM.OM_Handler Self.OM = OM_Handler print( Self.OM )
解决方案分析
你的方案的优缺点
你用类变量存储实例的方式确实解决了重复初始化的问题,但缺点很明显:
- 类变量属于全局状态,会拉高代码耦合度,后续如果需要创建多个
OM实例,这个机制直接失效(类变量会被最后一个实例覆盖)。 - 全局状态不利于测试,单元测试时容易出现状态污染的问题。
更优的实现方式
1. 依赖注入(推荐)
这是最清晰、解耦的方式——创建Config实例时,直接把已初始化好的OM实例传递进去。
修改后的VTE类:
class VTE: def __init__( Self ) : Self.OM = OM( Debug_Mode = False ) # 加载Config模块后,把OM实例传递给Config的初始化方法 CFG = Self.OM.Load_Module( 'Config' ) Self.Config = CFG.Config( Self.OM ) Self.Config.Config_Loader( )
修改后的Config类:
class Config: def __init__( Self , om_instance ) : Self.OM = om_instance Self.Config_Entries = { } print( Self.OM )
这种方式完全消除了全局状态,Config不需要关心OM实例的来源,只负责使用传入的实例即可,代码耦合度极低,后续扩展和测试都更方便。
2. 单例模式
如果你的OM类确实只需要一个全局实例,可以实现单例模式,确保整个程序中只会初始化一次:
修改后的OM类:
class OM: _instance = None def __new__( cls, Debug_Mode = False ): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.Debug_Mode = Debug_Mode cls._instance.Registered_Modules = { } print( "Initialized" ) return cls._instance # 避免重复执行初始化逻辑 def __init__( Self , Debug_Mode = False ): pass
这样不管在VTE还是Config中调用OM(),都会返回同一个实例,不会重复打印"Initialized"。但单例模式同样存在全局状态的问题,只适合确实需要唯一实例的场景。
3. 模块级别的单例
Python的模块本身就是天然单例,你可以在OM脚本中直接初始化一个实例,其他脚本导入这个实例即可:
OM脚本:
class OM: def __init__( Self , Debug_Mode = False ): print( "Initialized" ) Self.Debug_Mode = Debug_Mode Self.Registered_Modules = { } # 模块级别初始化实例 om_instance = OM( Debug_Mode=False )
VTE类中使用:
from OM import om_instance class VTE: def __init__( Self ) : Self.OM = om_instance CFG = Self.OM.Load_Module( 'Config' ) CFG.Config_Loader( )
Config类中使用:
class Config: def __init__( Self ) : from OM import om_instance Self.OM = om_instance Self.Config_Entries = { } print( Self.OM )
这种方式简单直接,但同样属于全局状态,灵活性不如依赖注入。
总结
优先选择依赖注入,它最符合软件工程设计原则(单一职责、依赖倒置),代码解耦性强,维护和测试都更方便。如果确实需要全局唯一实例,再考虑单例模式或模块级实例,尽量避免使用类变量存储实例的方式。
内容的提问来源于stack exchange,提问作者NumeroUnoDE

