添加网站关键词,手机主题如何自己制作网站,平罗县住房和城乡建设局网站,广州网站营销优化qq在Python中#xff0c;单例模式有多种实现方式#xff0c;下面介绍几种常见的形式#xff1a;使用模块#xff1a;Python的模块就是天然的单例模式#xff0c;因为模块在第一次导入时#xff0c;会生成.pyc文件#xff0c;当第二次导入时#xff0c;就会直接加载.pyc文…在Python中单例模式有多种实现方式下面介绍几种常见的形式使用模块Python的模块就是天然的单例模式因为模块在第一次导入时会生成.pyc文件当第二次导入时就会直接加载.pyc文件而不会再次执行模块代码。因此我们只需把相关的函数和数据定义在一个模块中就可以获得一个单例对象了。使用装饰器使用装饰器来装饰一个类使其只能生成一个实例。使用类方法new通过重写类的__new__方法来实现单例。使用元类metaclass通过元类来控制类的创建过程确保只生成一个实例。使用共享属性通过将实例的__dict__属性指向同一个字典从而使得多个实例共享相同的状态但这并不是严格意义上的单例因为多个实例的id可能不同但状态共享。下面分别给出这些方式的代码示例1. 使用模块创建一个模块比如叫做singleton_module.py里面定义需要的变量和函数。然后其他地方导入这个模块这个模块就是单例的。2. 使用装饰器def singleton(cls): instances {} def get_instance(*args, **kwargs): if cls not in instances: instances[cls] cls(*args, **kwargs) return instances[cls] return get_instance singleton class MyClass: pass3. 使用__new__方法class Singleton: _instance None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance # 或者使用更简洁的方式利用基类 class SingletonBase: _instance None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance super().__new__(cls, *args, **kwargs) return cls._instance class MyClass(SingletonBase): pass4. 使用元类class SingletonMeta(type): _instances {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] super().__call__(*args, **kwargs) return cls._instances[cls] class MyClass(metaclassSingletonMeta): pass5. 使用共享属性Borg模式class Borg: _shared_state {} def __init__(self): self.__dict__ self._shared_state class MyClass(Borg): pass6. 使用全局变量不推荐但也是一种方式在一个模块中定义一个全局变量然后通过函数来获取这个变量确保只有一个实例。7. 使用线程安全的单例模式适用于多线程环境import threading class Singleton: _instance None _lock threading.Lock() def __new__(cls, *args, **kwargs): if not cls._instance: with cls._lock: if not cls._instance: cls._instance super().__new__(cls, *args, **kwargs) return cls._instance # 或者使用模块级的锁注意在多线程环境下需要确保单例的创建过程是线程安全的。上面的例子中我们使用了双重检查锁定模式Double-Checked Locking Pattern。8. 使用lru_cachePython 3.2from functools import lru_cache lru_cache(maxsize1) class MyClass: pass但请注意lru_cache通常用于函数用于类时它缓存的是类的实例但类本身可能被多次调用但返回的是同一个实例。然而这种方式并不常见而且需要注意类的参数问题。实际上单例模式在Python中并不像在静态语言中那样必要因为我们可以通过模块来共享状态。但是如果需要以上几种方式都可以实现单例。选择哪种方式取决于具体需求比如是否要求线程安全是否希望延迟初始化等。通常情况下使用模块或者装饰器的方式比较简单而使用元类的方式则更加灵活和强大。以下是 Python 中单例模式的几种常见实现方式1.使用模块实现推荐Python 模块本身就是天然的单例模式# singleton_module.py class Singleton: def __init__(self): self.value None def do_something(self): return fDoing something with {self.value} singleton_instance Singleton() # 在其他文件中使用 from singleton_module import singleton_instance singleton_instance.value Hello2.使用装饰器实现def singleton(cls): _instances {} def get_instance(*args, **kwargs): if cls not in _instances: _instances[cls] cls(*args, **kwargs) return _instances[cls] return get_instance singleton class Database: def __init__(self): print(Database initialized) self.connection None def connect(self): self.connection Connected # 使用 db1 Database() # 输出: Database initialized db2 Database() print(db1 is db2) # True3.使用__new__方法实现class Singleton: _instance None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance super().__new__(cls) return cls._instance def __init__(self, nameNone): if not hasattr(self, initialized) or name: self.name name self.initialized True # 使用 s1 Singleton(First) s2 Singleton(Second) print(s1 is s2) # True print(s1.name) # First (不会变成Second)4.使用元类实现class SingletonMeta(type): _instances {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] super().__call__(*args, **kwargs) return cls._instances[cls] class Logger(metaclassSingletonMeta): def __init__(self, log_fileapp.log): self.log_file log_file self.logs [] def log(self, message): self.logs.append(message) print(f[LOG] {message}) # 使用 logger1 Logger(app.log) logger2 Logger(another.log) # 参数被忽略 print(logger1 is logger2) # True print(logger1.log_file) # app.log5.Borg 模式共享状态单例所有实例共享相同状态但不是严格意义上的单例class Borg: _shared_state {} def __init__(self): self.__dict__ self._shared_state self.state Init def __str__(self): return self.state class YourClass(Borg): pass # 使用 obj1 YourClass() obj2 YourClass() obj1.state Running print(obj2.state) # Running print(obj1 is obj2) # False (不同对象但状态共享)6.线程安全的单例import threading class ThreadSafeSingleton: _instance None _lock threading.Lock() def __new__(cls, *args, **kwargs): if not cls._instance: with cls._lock: if not cls._instance: cls._instance super().__new__(cls) return cls._instance def __init__(self, configNone): if not hasattr(self, initialized): self.config config or {} self.initialized True7.使用functools.lru_cache(Python 3.8)from functools import lru_cache class SingletonClass: def __init__(self, value): self.value value lru_cache(maxsize1) def get_singleton(value): return SingletonClass(value) # 使用 obj1 get_singleton(test) obj2 get_singleton(test) # 返回缓存的实例 print(obj1 is obj2) # True8.使用类方法实现class ConfigManager: _instance None classmethod def get_instance(cls): if cls._instance is None: cls._instance cls() return cls._instance def __init__(self): if not hasattr(self, initialized): self.settings {} self.initialized True # 使用 config1 ConfigManager.get_instance() config2 ConfigManager.get_instance() print(config1 is config2) # True选择建议简单场景使用模块方式最简单直接需要继承使用元类或装饰器多线程环境使用线程安全版本需要控制初始化使用__new____init__配合共享状态而非单实例使用 Borg 模式最佳实践示例综合版import threading from typing import Any class Singleton(type): 线程安全的单例元类 _instances {} _lock threading.Lock() def __call__(cls, *args: Any, **kwargs: Any) - Any: with cls._lock: if cls not in cls._instances: instance super().__call__(*args, **kwargs) cls._instances[cls] instance return cls._instances[cls] class DatabaseConnection(metaclassSingleton): def __init__(self, connection_string: str ): if not hasattr(self, _initialized): self.connection_string connection_string self._initialized True print(fDatabase connection established: {connection_string}) def query(self, sql: str): print(fExecuting: {sql}) # 使用 db1 DatabaseConnection(mysql://localhost:3306) db2 DatabaseConnection(different_connection) # 第二个参数被忽略 print(db1 is db2) # True选择哪种方式取决于具体需求模块方式在大多数情况下是最简单、最 Pythonic 的实现。