类的内置方法(魔法方法)
凡是在类内部定义,以——开头——结尾的方法,都是类的内置方法,也称之为魔法方法
类的内置方法, 会在某种条件下自动触发
内置方法如下:
__ 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>