一、类的内置方法(魔术方法)
类的内置方法:
凡是在类内部定义,以__ 开头 __ 结尾 (如__ init __) 的方法都是类的内置 方法,也称为魔术方法
类的内置方法,会在某种条件满足下自动触发。
内置方法如下:
__ new __ __:在 __ __ init __触发前,自动触发,调用该类时,内部会通过
__ new__ 产生一个新的对象。
__ init __ :在调用类时自动触发。通过产生的对象调用 __ init __ ()
# 1
class Demo(object):
#条件:__new__: 在__init__前自动触发
def __new__(cls, *args, **kwargs):
print('此处是__new__方法的执行')
#python内部通过object调用内部的__new__实现产生一个空的对象---->内存地址
return object.__new__(cls, *args, **kwargs)
def __init__(self):
print('此处是__init__方法的执行')
demo_obj = Demo()
print(demo_obj) #<__main__.Demo object at 0x103d887f0>
'''
结果:
此处是__new__方法的执行
此处是__init__方法的执行
<__main__.Demo object at 0x103d887f0>
'''
# 2
class Demo1(object):
#__getattr__:在'对象.属性'获取属性时,若'属性没有'时触发
def __getattr__(self, item):
print('此处是__getattr__方法的执行')
print(item)
#return 想要返回的值
return 'tank is very very handsome'
demo1_obj = Demo1()
print(demo1_obj.x, '想要返回的值')
'''
结果:
此处是__getattr__方法的执行
x
tank is very very handsome 想要返回的值
'''
demo1_obj.x = 10
print(demo1_obj.x, '属性有时不会触发__getattr__...')
'''
结果:
10 属性有时不会触发__getattr__...
'''
#3
#条件:__getattribute__ :在'对象.属性'获取属性时,无论'属性有没有'都会触发。
class Demo2(object):
def __getattribute__(self, item):
print(item, '<----打印属性名字')
return self
# return self.__dict__[item] #递归,死循坏
#注意此处不能通过 对象.属性,否则会产生递归调用,程序崩溃
#getattr:内部调用了----->__getattribute__
#return getattr(self, item)
#注意:只要__getattr__ 与__getattribute__ 同时存在类的内部,只会触发__getattribute__
demo_obj2 = Demo2()
print(demo_obj2.x)
'''
结果:
x <----打印属性名字
<__main__.Demo2 object at 0x1088516d0>
'''
#4
# 条件:当'对象.属性 = 属性值',添加或修改属性时触发
class Demo3(object):
def __init__(self):
pass
def __setattr__(self, key, value): #key---->对象.属性名 value----> 属性值
print('此处是__setattr__方法的执行')
print(key, value)
#出现递归
#self.key = value
#print(self.__dict__)
#此处是对对象的名称空间---》字典进行操作
self.__dict__[key] = value
#原来设置属性时,会自动触发父类中的__setattr__, 内部为对象添加x属性,值为20
demo_obj3 = Demo3()
print(demo_obj3.__dict__)#{}
demo_obj3.x = 10
print(demo_obj3) #此处是__setattr__方法的执行
#x 10
#<__main__.Demo3 object at 0x10fe006d0>
print(demo_obj3.__dict__) #{'x': 10}
# 5
# 条件:在打印对象时触发
# 注意:该方法必须要有一个'字符串'返回值
class Demo4(object):
def __str__(self):
print('此处是__str__方法的执行')
return '111' #如果没有返回值时会报错
demo_obj4 = Demo4()
print(demo_obj4) #111,
# 6
# #条件:在调用对象 '对象+()'时触发
class Demo5(object):
def __call__(self, *args, **kwargs):
print('此处是__call__方法的执行')
#调用对象时返回的值
return [1,2,3,4,5]
demo_obj5 = Demo5()
print(demo_obj5()) #此处是__call__方法的执行
#[1, 2, 3, 4, 5]
# 7
# 在对象通过'对象[key]'获取属性时触发
class Demo6(object):
def __getitem__(self, item):
print('此处是__getitem__方法的执行')
print(item)
return self.__dict__[item]
demo6_obj = Demo6()
demo6_obj.x = 10
print(demo6_obj['x'])
'''
结果:
此处是__getitem__方法的执行
x
10
'''
#8
#在对象通过'对象[key] = value'设置属性时触发
class Demo7(object):
def __setitem__(self, key, value):
print('此处是__setitem__方法的执行')
print(key, value)
print(self.__dict__)
self.key = value
print(self.__dict__)
self.__dict__[key] = value
demo7_obj = Demo7()
demo7_obj['x']= 10
'''
结果:
此处是__setitem__方法的执行
x 10
{}
{'key': 10}
'''
单例模式:
-单例模式是一种设计模式
-指的是在确定‘’类中的属性与方法‘’不变时,需要反复用该类,让所有的对象都执行同一个内存地址
优点:节省内存空间
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
foo_obj1 = Foo(10, 20)
print(foo_obj1.__dict__) #{'x': 10, 'y': 20}
print(foo_obj1) #<__main__.Foo object at 0x10dfe86d0>
foo_obj2 = Foo(10, 20)
print(foo_obj2.__dict__) ##{'x': 10, 'y': 20}
print(foo_obj2) #<__main__.Foo object at 0x10065e910>
单例模式方法:
1.通过classmethod
2.通过装饰器实现
3.通过__ new __ 实现
4.通过导入模块实现
5.通过元类实现
import setting
#通过classmethod
class MySQL:
#一个默认是,用来判断对象是否存在,对象不存在证明值是None
#__instance 是类的属性,可以由类来调用
__instance = None #--->执行到代码
#__instacne = obj
def __init__(self, host, port):
self.host = host
self.port = port
@classmethod
def singlethon(cls,host,port): #单例方法 ----》类方法
print('cls:',cls)
#判断__instance中没有值,证明没有对象
if not cls.__instance:
#产生一个对象并返回
obj = cls(host, port)
print('obj:',obj)
#此时的None转变为obj
cls.__instance = obj
return obj
#若__instance 中有值,证明对象已经存在。证明对象已经存在,则直接返回对象
else:
return cls.__instance
def start_mysql(self):
print('启动mysql')
def close(self):
print('关闭mysql')
obj1 = MySQL.singlethon(setting.host, setting.port)
print(obj1)
obj1.start_mysql()
obj2 = MySQL.singlethon(setting.host, setting.port)
print(obj2)
print(obj2.__dict__)
obj3 = MySQL.singlethon(setting.host, setting.port)
print(obj3) #<__main__.MySQL object at 0x11034acd0>
print(obj3.__dict__) #{'host': '192.168.0.0', 'port': 7070}