类的内置方法及单例模式
一、类的内置方法
类的内置方法(魔法方法):
凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。
类的内置方法,会在某种条件满足下自动触发。
1.__new__:
条件: 在__init__触发前,自动触发。
1 # 条件: __init__: 在调用类时自动触发。 2 def __init__(self): 3 print('执行__init__') 4 # 条件: __new__: 在__init__触发前,自动触发。 5 def __new__(cls, *args, **kwargs): 6 print('执行__new__') 7 # python内部通过object调用内部的__new__实现产生一个空的对象 ---> 内存地址 8 return object.__new__(cls, *args, **kwargs) 9 10 obj = Demo() 11 # 输出: 12 执行__new__ 13 执行__init__
2.__init__:
条件: 在调用类时自动触发。
1 1 # 条件: __init__: 在调用类时自动触发。 2 2 def __init__(self): 3 3 print('执行__init__') 4 4 obj = Demo()
3.__getattr__:
条件: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。
1 # 条件: __getattr__: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。 2 def __getattr__(self, item): 3 print('执行__getattr__') 4 # return 想要返回的值 5 return item
4.__getattribute__:
条件: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。
1 # 条件: __getattribute__: 在 “对象.属性” 获取属性时,无论"属性有没有"都会触发。 2 def __getattribute__(self, item): 3 # print('执行__getattribute__') 4 print(self.__dict__) # 注意: 此处不能通过 对象.属性,否则会产生递归调用,程序崩溃 5 # 注意: 只要__getattr__与__getattribute__同时存在类的内部,只会触发__getattribute__。
5.__setattr__:
条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发
1 # 条件: __setattr__: 当 “对象.属性 = 属性值”, 添加或修改属性时触发 2 def __setattr__(self, key, value): # key---> 对象.属性名 value ---》 属性值 3 print('执行__setattr__') 4 # print(key, value) 5 # self.key = value # 出现递归 6 # 此处是对 对象的名称空间 ---》 字典进行操作 7 self.__dict__[key] = value 8 print(self.__dict__)
6.__call__:
条件: 在调用对象 “对象 + ()” 时触发。
1 # 条件: __call__: 在调用对象 “对象 + ()” 时触发。 2 def __call__(self, *args, **kwargs): 3 print('执行__call__') 4 return self
7.__str__:
条件: 在打印对象时触发。
注意: 该方法必须要有一个 “字符串” 返回值。
1 # 条件: __str__: 在打印对象时触发。 2 def __str__(self): 3 print('执行__str__') 4 return '123' 5 # list1 = list([1, 2, 3, 4]) 6 # print(list1) ---> return [1, 2, 3, 4] 7 # 注意: 该方法必须要有一个 “字符串” 返回值。
8.__getitem__:
条件: 在对象通过 “对象[key]” 获取属性时触发
1 # 条件: __getitem__: 在对象通过 “对象[key]” 获取属性时触发 2 def __getitem__(self, item): 3 print(item) 4 print('执行__getitem__')
9.__setitem__:
条件: 在对象通过 “对象[key]=value值” 设置属性时触发。
1 # 条件: __setitem__: 在对象通过 “对象[key] = value值” 设置属性时触发。 2 def __setitem__(self, key, value): 3 print('执行__setitem__') 4 print(self.__dict__) 5 self.__dict__[key] = value 6 print(self.__dict__)
二、单例模式
单例模式:
指的是在确定 "类中的属性与方法" 不变时,需要反复调用该类,产生不同的对象,会产生不同的内存地址,造成资源的浪费。
让所有类在实例化时,指向同一个内存地址,称之为单例模式。 ----> 无论产生多个对象,都会指向单个实例。
- 单例的优点:
节省内存空间。
单例模式:
1.通过classmethod
2.通过装饰器实现
3.通过__new__实现
4.通过导入模块时实现
5.通过元类实现。
1 HOST = '192.168.0.1' 2 PORT = 1124 3 4 5 class MySQL: 6 7 single_obj = None 8 9 def __init__(self, host, port): 10 self.host = host 11 self.port = port 12 13 @classmethod 14 def singleton(cls, host, port): # 单例方法 ---> 类方法 15 # 判断single_obj中若没有值,证明没有对象 16 if not cls.single_obj: 17 # 产生一个对象并返回 18 obj = cls(host, port) 19 # None ---> obj 20 cls.single_obj = obj 21 22 # 若single_obj中有值,证明对象已经存在,则直接返回该对象 23 return cls.single_obj 24 25 def start(self): 26 print('启动MySQL') 27 28 def close(self): 29 print('关闭MySQL') 30 31 32 obj1 = MySQL.singleton(HOST, PORT) 33 print(obj1.host) 34 obj2 = MySQL.singleton(HOST, PORT) 35 print(obj2.port)