【Python】创建 final +单例模式 的 管理/分配资源类

本文深入探讨了Python中的单例模式实现及其潜在陷阱,特别是在与__init__方法交互时。同时,介绍了如何使用final装饰器来限制类的子类化,确保类的最终性。适用于Python 3.6及以上版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

keywords: final; subclass; Singleton;

1 磨刀

1.1 @final 装饰类

from typing import Type, TypeVar

T = TypeVar('T', bound=Type)

def _init_subclass(cls: T, *args, **kwargs) -> None:
    raise TypeError('Subclassing final classes is restricted')

def final(cls: T) -> T:
    """Marks class as `final`, so it won't have any subclasses."""
    setattr(cls, '__init_subclass__', classmethod(_init_subclass))
    return cls

? 代码来源:pypi.org > final-class 0.1.21

注意:该定义的 @final 类装饰器 仅在 > Python3.6 有效,因为 python 3.6 以上可以使用 __init_subclass__ 2
在 > python 3 and < python 3.6 的版本上使用不会有错误抛出,代码可以正常运行,但是继承被 @final 装饰的类也不会有错误抛出。

未在 python 2.x 上测试。

1.2 单例模式

class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls, *args, **kw)
        return cls.instance

    def the_left_class_func(self): pass
  • 这段位置用于简单解释代码。3

编写特殊方法 def __new__(cls, ...etc...): 中的内容时,该类
继承自 type 类使用

return type.__new__(cls)
or
return super().__new__(cls)

与 继承自 object 类使用

return object.__new__(cls, *args, **kw)
or
return super().__new__(cls, *args, **kw)

之间的 区别 和 使用 可能会遇到的问题 参考 ? 特殊方法 > __new__ (不是很详细,仅供参考)

特殊方法 > __new__ 链接的备用链接(防止更新博客内容后 #id 内链/锚 失效)

如果编写 __new__ 特殊方法遇到问题,一定要参考这篇 blog ☝️。

2 砍柴

2.1 Code(实例)

  • 待完善。
@final
class Resource(object):
    def __new__(cls, *args, **kw):  # Singleton
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls, *args, **kw)
        return cls.instance

    def __init__(self):
        
    def manage(self):
        pass

3 - [ ] 单例模式的陷阱!!!- 小心 __init__

陷阱:
Reference:

  1. https://stackoverflow.com/questions/51151836/singleton-typeerror-object-takes-no-parameters

    注意评论区:

    You should find a better Singleton implementation if you want to have a constructor.
    That one will call __init__ every time you call Singleton(), and that’ll reset the name attribute.
    (For example if you do a = Singleton('foo'); Singleton('bar'); print(a.name) you’ll get bar as output)

  2. https://blog.youkuaiyun.com/qq_29757283/article/details/85055204

使用 __init__:

Python 3.6:

class Singleton(object):
    _inst = None
 
    def __new__(cls, *args,  **kwargs):
        if not cls._inst :
            cls._inst = super(Singleton, cls).__new__(cls)
        return cls._inst
    
    def __init__(self, a_args):
        self.a_args = a_args

上面的代码在 python3.6 中可以 work

python 3.6 和 python3.7 在 __new__ 机制上有所不同,请自行探究。

本段代码参考: Python3.6单例模式报错TypeError: object() takes no parameters的解决方法

注:
推荐在模块文件内初始化一个全局类实例,其它 .py 文件位置导入该类实例。
这也是单例的效果。
可控性更强,更容易理解。



Reference

升级 python 版本(到 3.6/3.7)

参考:How to install Python 3.7 on Raspberry Pi 来升级 LINUX 上的 python 版本。

命令完全和该链接上一样,除了修改版本号为你想要安装的 python 版本,以及不要删除 /usr/bin/ 下的 (如)python3.5

/usr/bin/python3 是软连接,
/usr/bin/python3.5 不是软链接!!!


  1. pypi: final-class 0.1.2 ↩︎

  2. Emulating Final classes in Python ↩︎

  3. Python 设计模式 - 单例模式 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值