Python 魔术方法
#常用魔术方法
#魔术方法不需要用户调用,会在特定的时刻自动执行的方法就是魔术方法
#__init__魔术方法 初始化魔术方法
'''
触发时机:做出对象,对象初始化的时候触发
功能:为对象添加成员[肯定不会添加到类中]
参数:至少一个self接受对象,其他根据情况添加
返回值:无
'''
import random
class Human:
#属性
age = 1
color = 'yellow'
#方法
def __init__(self,diyname):
#为对象添加成员
#print(self)
self.hair = '自然卷'
self.name = 'diyname'
#随机产生性别
if random.randrange(0,2) == 1:
self.sex = '男'
else:
self.sex = '女'
def eat(self):
print('吃饭')
def drink(self):
print('喝水')
#实例化对象
zw = Human('旺旺')
print(zw.__dict__)
print(Human.__dict__)
#__new__ 构造方法
'''
触发时机:创建对象的时候触发(在语法上和init的触发相同)
功能:控制对象的创建过程
参数:至少一个cls接受当前的类,其他根据情况决定
返回值:有返回值也可以没有(这里的返回值通常返回对象)
'''
class Human:
#属性
age = 18
sex = 'man'
#方法
def __new__(cls,diyname):
#print('new方法被触发')
print(cls)
return object.__new__(cls)
def __init__(self,diyname):
pass
def sleep(self):
print('睡觉')
def eat(self):
print('吃饭')
#实例化对象
sy = Human('阳') #1.创建对象(new) 2.对对象进行初始化操作(init)
print(sy)
#单例设计模式
class WangYingsong:
#属性
color = 'yellow'
age = 27
name = '应松'
#声明了一个类成员属性用于保存创建的对象
obj = None
#方法
def __new__(cls):
#检测是否已经制作过对象
if cls.obj == None:#没有做过对象
#实例化对象(存入当前类中)
cls.obj = object.__new__(cls)
return cls.obj
else:#做过对象,直接将类中保存的对象返回
return cls.obj
def study(self):
print('好好学习天天向上')
def eat(self):
print('吃饭')
#实例化对象1
ys1 = WangYingsong()
print(ys1)
#实例化对象2
ys2 = WangYingsong()
print(ys2)
#实例化对象3
ys3 = WangYingsong()
print(ys3)
#del魔术方法
'''
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.对象的所有变量被del的时候]
功能:处理对象使用完毕时候的成员或者资源的回收
参数:一个self接受对象
返回值:无
'''
class Human:
#属性
money = 1000
sex = 'man'
age = 18
name = '小松松'
#方法
def eat(self):
print('吃饭')
def drink(self):
print('喝水')
#del魔术方法 析构方法
def __del__(self):
print('del方法被触发')
#实例化对象
ss = Human()
#将对象赋值给另外一个变量
yy = ss
print(ss)
print('----------')
del ss
del yy
print('----------')
#文件读取操作
'''
1.打开文件
2.读取文件
3.关闭文件
'''
'''
fp = open('11.txt','r')
fp.read()
fp.close()
'''
class ReadFile:
#打开文件(构造)
def __init__(self,filename):
#打开文件将文件io对象保存在对象成员
self.fp = open(filename,'r')
#读取文件
def fread(self):
return self.fp.read()
#关闭文件(析构)
def __del__(self):
print('关闭文件操作')
self.fp.close()
#实例化对象
one = ReadFile('11.txt')
txt = one.fread()
print(txt)
#call魔术方法
'''
触发时机:把对象当做函数调用的时候自动触发
功能:简化操作
参数:至少一个self接受当前对象,其他参数根据程序决定
返回值:根据程序决定
'''
class Human:
#属性
sex = 'man'
age = 18
color = 'yellow'
#方法
def eat(self):
print('吃饭')
def sleep(self):
print('睡觉')
def __call__(self):
print('call魔术方法被触发')
#实例化对象
bb = Human()
print(bb)
#把对象当做函数调用的时候
bb()
#做蛋糕的类
class MakeCake:
#和面
def huomian(self):
print('和面操作')
#发酵
def fajiao(self):
print('发酵操作')
#烘烤
def hongkao(self):
print('烘烤操作')
#切形状
def zaoxing(self):
print('切形状')
#抹奶油
def monaiyou(self):
print('抹奶油操作')
#打包
def dabao(self):
print('打包操作')
return '完整的盒装蛋糕'
#获取蛋糕的方法
def __call__(self,who):
print('制作者:',who)
self.huomian()
self.fajiao()
self.hongkao()
self.zaoxing()
self.monaiyou()
result = self.dabao()
return result
#实例化对象
mc = MakeCake()
#用户获取蛋糕
r = mc('大厨')
print(r)
#len魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:只有一个参数self接受当前对象
返回值:必须返回整型
'''
class Human:
#属性
sex = 'man'
age = 18
color = 'yellow'
#方法
def eat(self):
print('吃饭')
def drink(self):
print('喝水')
#魔术方法__len__
def __len__(self):
print('len方法被触发')
#去掉所有带下划线开头和结尾的成员
#获取所有带下划线的成员
result = {k:v for k,v in Human.__dict__.items() if k.startswith('__') and k.endswith('__')}
print(result)
#获取所有成员
alls = Human.__dict__
#获取用户定义的普通成员个数 相减
return len(alls ) - len(result)
#实例化对象
mmf = Human()
print(mmf)
result = len(mmf)
print(result)
#str魔术方法
'''
触发时机:使用print打印对象的时候或者str(对象)都可以触发
功能:定义对象转换为字符串的结果
参数:一个self接受对象
返回值:必须返回字符串类型
'''
class Human:
#属性
sex = 'man'
age = 18
name = 'wangcheng'
#方法
def la(self):
print('lalala')
def sa(self):
print('谁先来')
#魔术方法__str__
def __str__(self):
print('str被触发')
return 'laxini'
return self.name
#实例化对象
wc = Human()
#print(wc)
result = str(wc)
print(result)
#repr魔术方法
'''
触发时机:使用repr(对象)的时候触发
功能:定义repr函数的结果
参数:一个self接收当前对象
返回值:必须是字符串类型
'''
class Human:
#属性
sex = 'woman'
age = 18
height = '178cm'
#方法
def think(self):
print('思想')
def dream(self):
print('I have a dream')
#__repr__魔术方法
def __repr__(self):
print('repr方法被触发')
return 'zw对象'
#设定__str__和__repr__的魔术方法相同
__str__ = __repr__
#实例化对象
zw = Human()
result = repr(zw)
print(result)
#测试repr函数
var = '123'
print(var)
result = repr(var)
print(result)
#__bool__魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:根据某个规则确定对象的布尔值转换结果
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
class Human:
#属性
sex = 'woman'
age = 20
color = 'yellow'
#方法
def getMoney(self):
print('赚钱')
def spendMoney(self):
print('花钱')
#__bool__魔术方法
def __bool__(self):
#print('bool方法被触发')
#设置当前对象 男 -> True 女 -> False
if self.sex == 'man':
return True
return False
#实例化对象
bb = Human()
result = bool(bb)
print(result)
#format魔术方法
class Human:
#属性
name = 'feng'
sex = 'man'
age = 18
#方法
def lang(self):
print('划船一身浪')
def show(self):
print('xiufeng')
#__format__魔术方法
def __format__(self,arg):
print('format方法被触发')
print(arg)
# > < ^
#将arg(限定符号)进行拆分
flag = arg[0] # @
align = arg[1] # > < ^
num = int(arg[2:]) # 6
#判断对齐方式
if align == '<':#左对齐
result = self.name.ljust(num,flag)
elif align == '>':#右对齐
result = self.name.rjust(num,flag)
elif align == '^':#居中对齐
result = self.name.center(num,flag)
return result
#实例化对象
sf = Human()
str = '{:#^10}去洗澡'
result = str.format(sf)
print(result)
#描述符相关的魔术方法
#描述符类
class Decription:
#成员属性 共享值的操作
def __init__(self):
self.var = 'zhengyang'
#定义三个操作
#获取成员属性
def __get__(self,obj,cls):#self描述符对象 obj接受描述的成员属性username的对象e cls描述成员属性username所在的类Email
#print(obj,cls)
#隐藏名字中间的一个字符
result = self.var[0]+'*'+self.var[-1]
return result
#设置成员属性
def __set__(self,obj,value):#self描述符对象 obj接受描述的成员属性username的对象e value设置的值
#设置时候,默认添加思密达
self.var = value + '思密达'
#删除成员属性
def __delete__(self,obj):#self描述符对象 obj接受描述的成员属性username的对象e
#删除self.var就可以删除username的访问操作
#根据密码是否为空决定是否可以删除用户名
if obj.password == '':
del self.var
else:
pass
class Email:
#属性
#希望对用户名进行管控(不是权限管控,而是内容管控)
username = Decription()#交接操作 将username的操作管控交给描述符类的一个对象
password = '123456'
#方法
def login(self):
print('登录')
def logout(self):
print('注销')
#实例化对象
e = Email()
#获取成员属性
print(e.username)
#设置成员属性
e.username = '张望'
print(e.username)
#删除成员属性
del e.username
print(e.username)
#描述符2
class Email:
#属性
#username = ''
password = ''
#方法
def __init__(self):
#设置var对象成员为描述符的三个方法工作
self.var = 'yang'
def login(self):
print('登录')
def logout(self):
print('注销')
#获取属性的操作
def getusername(self):
result = self.var[0] + '*' +self.var[-1]
return result
#设置属性的操作
def setusername(self,value):
self.var = value
#删除属性的操作
def delusername(self):
#删除的时候对self.var进行操作
del self.var
#将username属性交给property指定的函数管理
username = property(getusername,setusername,delusername)
#实例化对象
e = Email()
#获取成员属性
print(e.username)
#设置成员属性
e.username = 'yangjun'
print(e.username)
#删除成员属性
#del e.username
#print(e.username)
#描述符3
class Email:
#属性
#username = ''
password = ''
#方法
def __init__(self):
#为描述符添加的用于数据通讯的成员属性
self.var = '匿名'
def login(self):
print('登录')
def logout(self):
print('注销')
#获取操作
@property
def username(self):
result = self.var[0] + '*' + self.var[-1]
return result
#设置操作
@username.setter
def username(self,value):
self.var = value
#删除操作
@username.deleter
def username(self):
del self.var
#实例化对象
e = Email()
#获取用户名
print(e.username)
#修改用户名
e.username = 'sun'
print(e.username)
#删除用户名
#del e.username
#print(e.username)
#与属性相关的魔术方法
class Man:
#属性
sex = 'man'
age = 18
color ='yellow'
name = 'shizhipeng'
#方法
def __init__(self):
self.gf = 'cortana'
self.hobby = 'watchTV'
def chou(self):
print('piapia')
def keng(self):
print('坑娃的')
'''
#__getattr__()
触发时机:访问一个不存在的成员属性的时候触发
功能:1.防止访问不存在成员报错 2.可以为不存在的成员设置默认值
参数:一个self接受对象 一个参数接受要访问的不存在的成员名
返回值:可以有可以没有,如果有则是设置了访问的成员的值
def __getattr__(self,attrname):
#print(attrname)
if attrname == 'height':
return '175cm'
elif attrname =='weight':
return '75kg'
else:
return '对不起,不存在该属性'
'''
'''
#__getattribute__()
触发时机:访问对象成员时触发(无论是否存在)
功能:可以限制过滤指定成员的值的访问
参数:一个self接受当前对象 一个接受要访问的成员名
返回值:可以有,可以没有 推荐根据程序设定(一般有!)
def __getattribute__(self,attrname):
if attrname == 'name':
#不能通过当前对象访问成员(访问时绝对不允许使用[对象,成员名]的格式获取)触发递归!
return object.__getattribute__(self,attrname)
elif attrname == 'sex':
return object.__getattribute__(self,attrname)
else:
return'对不起,成员不存在或者不允许访问'
'''
#__setattr__
'''
触发时机:对成员属性进行设置的时候触发
功能:限制或者过滤对象成员的修改
参数:一个self接受当前对象 一个接受修改的成员名 一个要修改的成员值
返回值:没有返回值!
'''
def __setattr__(self,attrname,value):
#可以在设置成员属性时候进行判断
if attrname == 'sex' or attrname == 'name':
pass
else:
object.__setattr__(self,attrname,value)
#__delattr__ 魔术方法
def __delattr__(self,attrname):
#根据删除的内容决定是否允许删除
if attrname == 'hobby':
pass
else:
object.__delattr__(self,attrname)
#实例化对象
szp = Man()
'''
#获取对象的成员属性(getattr魔术方法)
print(szp.height)
print(szp.weight)
print(szp.length)
'''
#获取对象的成员属性(getattribute)
#print(szp.color)
#设置成员属性
#szp.sex = 'no man no woman'
#print(szp.sex)
#szp.name = '失了志'
#print(szp.name)
#szp.color = 'black'
#print(szp.color)
#删除成员属性
print(szp.__dict__)
del szp.gf
print(szp.__dict__)
#dir魔术方法
class Human:
#属性
sex = 'man'
age = 18
name = 'dog'
#方法
def eat(self):
print('吃饭')
def drink(self):
print('喝水')
#__dir__
def __dir__(self):
#获取所有可以访问的成员
lists = object.__dir__(self)
#过滤魔术方法 只留下自定义成员
newlists = []
for i in lists:
if i.startswith('__') and i.endswith('__'):
pass
else:
newlists.append(i)
return newlists
#实例化对象
qw = Human()
#获取当前对象中所有存在的成员
result = dir(qw)
print(result)
#其他魔术方法
#自定义我们自己的整型类
class Myint(int):
'''
#__add__加法的魔术方法(int类中本来就有)
def __add__(self,other):
#print('add方法被触发')
#print(self,other)
return int(self) - int(other)
'''
#__radd__反向加法的魔术方法(int类中本来就有)
def __radd__(self, other):
#print('radd方法被触发')
return int(self) * int(other)
#实例化对象
no1 = Myint(50)
#result = no1 + 15
#print(result)
'''
#练习:自定义一个整型,相加时进行的运算为10位数相乘+个位数相减
class Myint(int):
def __add__(self,other):
return int((self // 10) * (other // 10)) + int(self % 10 - other % 10)
no1 = Myint(18)
result = no1 + 25
print(result)
'''
#反向加法运算__radd__
result = no1 + 40
print(result)
'''
#练习:自定义一个整型,反向相加运算时获取2个数值的个位数的乘积作为结果
class Myint(int):
def __radd__(self, other):
return int(self % 10) * int(other % 10)
no1 = Myint(18)
result = 25 + no1
print(result)
'''
#比较运算
class Myint(int):
#__eq__ 相等魔术方法
def __eq__(self,other):
#print('eq方法被触发')
#print(self,other)
#自定义规则:如果2个数都能被6整除 相等 其余都不相等
if self % 6 == 0 and other % 6 == 0:
return True
else:
return False
#__gt__ 大于比较魔术方法
def __gt__(self,other):
if self % 5 > other % 5:
return True
else:
return False
#实例化对象
no1 = Myint(34)
no2 = Myint(63)
#相等运算
result = no1 == no2
print(result)
'''
#练习:只要个位数相等 就相等 其余都不相等
class Myint(int):
def __eq__(self,other):
if (self % 10) == (other % 10):
return True
else:
return False
no1 = Myint(12)
no2 = Myint(22)
result = no1 == no2
print(result)
'''
#大于比较运算
result = no1 > no2
print(result)