类的内置方法及单例模式

一、类的内置方法

类的内置方法(魔法方法):
  凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。

  类的内置方法,会在某种条件满足下自动触发。

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)
原文地址:https://www.cnblogs.com/hexianshen/p/11958230.html