[TOC]
凡是在类内部定义的,以——开头——结尾的方法,都是类的内置方法,也称之为魔法方法。
会在某种条件下满足自动触发。
——init——触发前,调用该类时,内部会通过——new——产生一个新的对象。
——init——:在调用类时自动触发,通过产生的对象自动调用——init——()(**——new——产生的新的对象 ,触发了——init——调用)
class Demo(object):##这个里面的object就是一个新式类 父类
# 在调用类时触发
def __init__(self):
print(‘在调用类时触发... ‘)
# Demo() 调用类
#####在调用类时触发...
# 条件__new__:在__init__触发前,自动触发。
def __new__(cls, *args, **kwargs):
print(‘此处是__new__方法的执行‘)
# python内部通过object调用内部的__new__实现产生一个空的对象,然后再去执行__init__
return object.__new__(cls, *args, **kwargs)
# Demo()
###此处是__new__方法的执行
###在调用类时触发...
class Demo:
#在“对象.属性”获取属性的时候,如果没有‘属性‘时触发
def __getattr__(self, item):##这个是属性名
print(‘此处是__getattr__方法的执行‘)
print(item)
return 123
obj = Demo()
print(obj.x)
>>>>>>>>>>>>>>>>>>
此处是__getattr__方法的执行
x
123
如果obj.x = 2
print(obj.x)
最后的结果就是
2###return的结果会被改为2 但是属性print值就不会触发
class Demo:
#__getattribute__:在“对象.属性”获取属性的时,无论属性有或者没有
#都会触发
y = 12
def __getattribute__(self,item):
print(item,‘----要打印的东西‘) #item指的是变量名
#如下面的例子,此处不能通过对象.属性 ,否则会产生递归,程序崩溃,
# print(self.__dict__)
# return self.__dict__[item]
# return self.__dict__[item]
obj = Demo()
# obj.x
obj.y = 2
print(obj.y,‘---打印出值‘) ###打印结果都是None
>>>>>>>>>>>>>>>
y ----要打印的东西
None ---打印出值
注意:只要——getattr 和——getattribute 同时存在的数据,只会触发——getattribute——
class Demo:
#只有当“对象.属性 = 属性值”,添加或者修改属性时触发
def __setattr__(self, key, value):
print(‘此处是__setattr__方法的执行‘)
print(key,value)
#下面的情况出现了递归
# self.key = value
print(self.__dict__)###打印的是一个空{}
self.__dict__[key] = value###这个是一个字典{‘x’:30} 把新加的值30放进去obj的名词空间里面,才可以打印的出来
obj = Demo()
obj.x = 2
obj.x = 30
print(obj.__dict__)#打印的是空字典,原来设置属性的时候,会自动触发父类中的__setattr__
#内部为对象添加x属性,值为20,如果把__setattr__删除,obj对象中的属性x 才会存在
>>>>>>>>>>>>>>>>
此处是__setattr__方法的执行
x 2
{}
此处是__setattr__方法的执行
x 30
{‘x‘: 2}
{‘x‘: 30}
class Demo:
#条件:在调用对象 “对象+()”时触发
def __call__(self, *args, **kwargs):
print("此处是__call__方法的执行")
return [1,2,3,4]
obj = Demo()
res = obj()
print(res)
>>>>>>>>>>>>
此处是__call__方法的执行
[1, 2, 3, 4]
class Demo:
#条件:在打印对象时触发
#该方法必须有一个字符串的返回值
def __str__(self):
print(‘此处是__str__的方法执行‘)
return ‘111‘
obj = Demo()
print(obj)
>>>>>>>>>>>>
此处是__str__的方法执行
111
class Demo:
#在对象通过“对象[key]”获取属性时触发
def __getitem__(self, item):
print(‘此处是__getitem__的方法执行‘)
print(item)
return self.__dict__[item]###这个是一个字典
obj = Demo()
obj.x = 2
print(obj[‘x‘])
>>>>>>>>>>>>>>>>>
此处是__getitem__的方法执行
x
2
定义:指的是在确定“类中的属性和方法”不变时,需要反复调用类,产生不同的对象,会产生不同的内存地址,造成资源的浪费。
让所有的类实例化,指向同一个内存地址,称之为单例模式------->无论产生多少个内存对象,都会指向一个实例。
class Foo:
def __init__(self,x,y):
self.x = x
self.y = y
foo_obj1 = Foo(10,20)
print(foo_obj1.__dict__)
print(foo_obj1)
foo_obj2 = Foo(20,30)
print(foo_obj2.__dict__)
print(foo_obj2)
##foo_obj1 和foo_obj2 的内存空间的地址不一样
>>>>>>>>>>>>>>>
{‘x‘: 10, ‘y‘: 20}
<__main__.Foo object at 0x000002B4F12BF2E8>
{‘x‘: 20, ‘y‘: 30}
<__main__.Foo object at 0x000002B4F12BF400>
1.通过classmethod
2.通过装饰器
3.通过——new——实现
4.通过元类实现
5.通过模块实现
setting中的值
HOST = ‘180.101.49.12‘
PORT = 443
import setting
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(setting.HOST,setting.PORT)
print(obj1)
obj2 = MySQL.singleton(setting.HOST,setting.PORT)
print(obj2)
>>>>>>>>>>>>>>>>>>>>
<__main__.MySQL object at 0x0000019B5F8FFF60>######现在这个内存地址就是一样了
<__main__.MySQL object at 0x0000019B5F8FFF60>
通过模块实现
#模块 demo
class Singleton:
pass
obj = Singleton()
#下面的是另外一个模块的调用
from demo import obj
print(obj)
from demo import obj
print(obj)
>>>>>>>>>>>>>>>>
<demo.Singleton object at 0x000001E1463044E0>
<demo.Singleton object at 0x000001E1463044E0>
通过装饰器
#用装饰器的方法
def singleton(cls):
__instance = {} ##这个字典是一个可变的类型,我每次往里面的值obj发生改变 这个的内存地址都不会变,所以是打印出来的内存地址都是一样的
def inner(*args, **kwargs):
if cls not in __instance:
obj = cls (*args,**kwargs)
__instance[cls] = obj
return __instance[cls]
return inner
@singleton
class Father:
pass
print(Father())
print(Father())
>>>>>>>>>>>>>
<__main__.Father object at 0x0000019FDD15F518>
<__main__.Father object at 0x0000019FDD15F518>
通过__new__ d的方法
class Singleton2:
__instance = None
def __new__(cls,*args,**kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
obj1 = Singleton2()
print(obj1)
obj2 = Singleton2()
print(obj2)
>>>>>>>>>>>>>>
<__main__.Singleton2 object at 0x0000023C04EFF518>
<__main__.Singleton2 object at 0x0000023C04EFF518>
原文:https://www.cnblogs.com/bs2019/p/11991678.html