keywords: final; subclass; Singleton;
Overview
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__
特殊方法遇到问题,一定要参考这篇 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:
- 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 doa = Singleton('foo')
;Singleton('bar')
;print(a.name)
you’ll getbar
as output) - 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
不是软链接!!!
Python 设计模式 - 单例模式 ↩︎