面向对象其它
一、单例模式
1、什么是设计模式
设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题的成熟的解决方案
使用 设计模式 是为了可重用代码、让代码更容易被他人理解、保证代码可靠性
2、单例设计模式
- 目的 —— 让 类 创建的对象,在系统中 只有 唯一的一个实例
- 每一次执行
类名()
返回的对象,内存地址是相同的
3、应用场景
4、如何创建单例模式
- 使用模块
- 使用装饰器
- 使用类
- 基于__new__方法实现(推荐使用,方便)
- 基于metaclass方式实现
1、使用模块
说明
Python 的模块就是天然的单例模式 系统规定
因为模块在第一次导入时,会生成
.pyc
文件,当第二次导入时,就会直接加载.pyc
文件,而不会再次执行模块代码
2、__new__
方法
说明
使用 类名() 创建对象时,
Python
的解释器 首先 会 调用__new__
方法为对象 分配空间__new__
是一个 由 object 基类提供的内置的静态方法,主要作用有两个:- 在内存中为对象 分配空间
- 返回 对象的引用
Python
的解释器获得对象的 引用 后,将引用作为 第一个参数,传递给__init__
方法重写__new__
方法 的代码非常固定!- 重写
__new__
方法 一定要return super().__new__(cls)
- 否则 Python 的解释器 得不到 分配了空间的 对象引用,就不会调用对象的初始化方法
注意:
__new__
是一个静态方法,在调用时需要 主动传递cls
参数举个栗子
1
2
3
4
5
6
7
8
9
10
11
12class Singleton(object):
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None
Singleton._instance = object.__new__(cls)
return Singleton._instance
def __init__(self):
pass
obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)
3、使用装饰器
举个栗子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def singleton(cls, *args, **kwargs):
instance = {}
def _singleton():
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return _singleton
class Singleton(object):
def __init__(self):
self.num_sum = 0
def add(self):
self.num_sum = 100
if __name__ == '__main__':
obj1 = Singleton()
obj2 = Singleton()
print(obj1, obj2)
4、使用类
举个栗子
1
2
3
4
5
6
7
8
9
10
11
12
13class Singleton(object):
__instance = None
def instance(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
Singleton.__instance = Singleton(*args, **kwargs)
return Singleton.__instance
obj1 = Singleton.instance()
obj2 = Singleton.instance()
5、使用元类
举个栗子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class SingletonType(type):
def __init__(self,*args,**kwargs):
super(SingletonType,self).__init__(*args,**kwargs)
def __call__(cls, *args, **kwargs): # 这里的cls,即Singleton类
print('cls',cls)
obj = cls.__new__(cls,*args, **kwargs)
cls.__init__(obj,*args, **kwargs) # Singleton.__init__(obj)
return obj
class Singleton(metaclass=SingletonType): # 指定创建Singleton的type为SingletonType
def __init__(self,name):
self.name = name
def __new__(cls, *args, **kwargs):
return object.__new__(cls)
obj = Singleton('xx')
二、type和isinstance
1、概述
Python为每一个object在创建的时候就指定了一个内部类型,当我们不知道一个变量是什么类型时,就需要通过一些方法来输出变量的类型,Python的type函数提供了这样的功能。type()返回任意Python对象的类型,而不局限于标准类型。
那么在程序中如何判断类型并根据判断结果进行相应的处理呢?首先可以通过type和is来进行
2、举个栗子
type来获取类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Test:
pass
class Test2(Test):
pass
if __name__ == "__main__":
x = 123 # int
print(type(x))
y = 3.1415 # float
print(type(y))
t1 = Test() # Test1
print(type(t1))
t2 = Test2() # Test2
print(type(t2))
s = 'sdf' # str
print(type(s))
b = True # bool
print(type(b))
li = ['s'] # list
print(type(li))
tup = ('sdf',) # tuple
print(type(tup))
dic = {'sdf': 132} # dict
print(type(dic))type来获取类型判断类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Test:
pass
class Test2(Test):
pass
if __name__ == "__main__":
x = 123 # int
print(type(x) is int)
y = 3.1415 # float
print(type(y) is float)
t1 = Test() # Test1
print(type(t1) is Test)
t2 = Test2() # Test2
print(type(t2) is Test2)
s = 'sdf' # str
print(type(s) is str)
b = True # bool
print(type(b) is bool)
li = ['s'] # list
print(type(li) is list)
tup = ('sdf',) # tuple
print(type(tup) is tuple)
dic = {'sdf': 132} # dict
print(type(dic) is dict)通过instance方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Test:
pass
class Test2(Test):
pass
if __name__ == "__main__":
x = 123 # True
print(isinstance(x, int))
y = 3.1415 # True
print(isinstance(y, float))
t1 = Test() # True
print(isinstance(t1, Test))
t2 = Test2() # True
print(isinstance(t2, Test))
# False
print(type(t2) is Test)
3、不同点
- type可以只接收一个参数,打印其未知的所属的类型;而isinstance只能判断是否属于某个已知类型
- isinstance可以判断子类对象是否继承于父类;而type不可以
- 应用场景不同;type主要用于获取未知变量的类型;isinstance主要用于判断A类是否继承于B类