类的内置方法(魔法方法)
凡是在类内部定义,以——开头——结尾的方法,都是类的内置方法,也称之为魔法方法
类的内置方法, 会在某种条件下自动触发
内置方法如下:
__ new __ : 在__ init __ 触发前触发,调用该类时会通过 __ new __ 产生一个新的对象
__ init __ : 在调用类时,自动触发。通过产生的对象自动调用 __ init __
'''
类的内置方法(魔法方法):
凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。
类的内置方法,会在某种条件满足下自动触发。
内置方法如下:
new: 在__init__触发前,自动触发。 调用该类时,内部会通过__new__产生一个新的对象。
init: 在调用类时自动触发。 通过产生的对象自动调用__init__()
'''
class Demo(object):
条件: __new__: 在__init__触发前,自动触发。
def __new__(cls, *args, **kwargs):
print('此处是__new__方法的执行')
python内部通过object调用内部的__new__实现产生一个空的对象 ---> 内存地址
return object.__new__(cls, *args, **kwargs)
条件: __init__: 在调用类时自动触发。
def __init__(self):
print('此处是__init__方法的执行')
__getattr__: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。
def __getattr__(self, item):
print('此处是__getattr__方法的执行')
print(item)
return 想要返回的值
return 'tank is very very handsome!!!'
条件: __getattribute__: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
def __getattribute__(self, item):
print(item, '<-----打印属性名字')
print(self.__dict__)
return self.__dict__[item]
注意: 此处不能通过 对象.属性,否则会产生递归调用,程序崩溃
getattr: 内部调用了 ----> __getattribute__
return getattr(self, item)
注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。
条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发
def __setattr__(self, key, value): # key---> 对象.属性名 value ---》 属性值
print('此处是__setattr__方法的执行')
print(key, value)
出现递归
self.key = value
print(self.__dict__)
此处是对 对象的名称空间 ---》 字典进行操作
self.__dict__[key] = value
条件: 在调用对象 “对象 + ()” 时触发。
def __call__(self, *args, **kwargs):
print('此处是__call__方法的执行')
调用对象时返回的值
return [1, 2, 3, 4, 5]
条件: 在打印对象时触发。
注意: 该方法必须要有一个 “字符串” 返回值。
def __str__(self):
print('此处是__str__方法的执行')
return '111'
在对象通过 “对象[key]” 获取属性时触发。
def __getitem__(self, item):
print('此处是__getitem__方法的执行')
print(item)
return self.__dict__[item]
在对象通过 “对象[key]=value值” 设置属性时触发。
def __setitem__(self, key, value):
print('此处是__setitem__方法的执行')
print(key, value)
print(self.__dict__)
self.key = value # {'key': value}
print(self.__dict__)
self.__dict__[key] = value
print(type)
demo_obj = Demo() # 此处是__init__方法的执行
print(demo_obj.x, '<----想要返回的值...')
demo_obj.x = 10
print(demo_obj.x, '<----属性有时不会触发__getattr__...')
原来设置属性时,会自动触发父类中的__setattr__,内部为对象添加x属性,值为20
demo_obj.y = 20
demo_obj.y = 30
print(demo_obj.dict)
res = demo_obj()
print(res)
print(demo_obj)
list1 = list([1, 2, 3, 4, 5])
print(list1)
print(demo_obj.x)
print(demo_obj, '<----- 打印的对象')
print(demo_obj['x'])
demo_obj['y'] = 300
print(demo_obj.y)
单例模式
'''
单例模式:
指的是在确定‘类中的属性与方法’不变时,需要反复调用该类,产生不同的对象,会产生不同的地址,造成资源的浪费
让所有的类在实例化时,指向同一个内存地址, 称之为单例模式。 ------> 无论产生多个对象,都会指向单个实例
单例模式的优点:
节省内存空间
'''
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
fool_obj1 = Foo(1, 2)
print(fool_obj1.__dict__)
print(fool_obj1)
fool_obj2 = Foo(1, 2)
print(fool_obj2.__dict__)
print(fool_obj2)
# {'x': 1, 'y': 2}
# <__main__.Foo object at 0x000001C92DFFDCC0>
# {'x': 1, 'y': 2}
# <__main__.Foo object at 0x000001C92E19F438>
# 单例模式
# 1.通过classmethod实现
class MYSQL:
# 首先设置一个默认值,用于判断对象是否存在,对象不存在证明是None
# __instance是类的属性,可以由类来调用
__instance = None
def __init__(self, host, port):
self.host = host
self.port = port
@classmethod
def singleton(cls, host, port):
# 首先判断__instance中若没有值,证明没有对象
if not cls.__instance:
# 产生一个对象并返回
obj = cls(host, port)
cls.__instance = obj
# 若__instance中有值,证明对象已经存在,则直接返回该对象
return cls.__instance
def start_mysql(self):
print('启动mysql')
def close(self):
print('关闭mysql')
obj1 = MYSQL.singleton('123.3.10.2', 3306)
print(obj1.__dict__)
print(obj1)
obj2 = MYSQL.singleton('14.21.20', 3306)
print(obj2.__dict__)
print(obj2)
obj1.start_mysql()
obj2.start_mysql()
结果:
{'x': 1, 'y': 2}
<__main__.Foo object at 0x000002AC7C7BF400>
{'x': 1, 'y': 2}
<__main__.Foo object at 0x000002AC7F806DD8>
{'host': '123.3.10.2', 'port': 3306}
<__main__.MYSQL object at 0x000002AC7F822240>
{'host': '123.3.10.2', 'port': 3306}
<__main__.MYSQL object at 0x000002AC7F822240>