python进阶
在写面向对象的笔记时,发现之前对魔法方法的了解一直不是很全面,所以导致自己在写类的时候不能够很好的去应用,魔法不够方法来凑,总是显式的去调用一些函数,不美观且也冗余,所以打算另开一篇博客专门整理魔法方法,以便可以更好的应用。
魔法方法
- _init_
语法:_init_(self,参数【可有可无】)
用途:构造函数,用于初始化对象实例,如果带参数,可以在实例化的过程中将参数赋值给对象
小例子:
class Dog():
def __init__(self,name,age,color):
self.name = name
self.age = age
self.color = color
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','seven months','white')
print(jelly) # <博客练习.tmp.Dog object at 0x7fbbb01a5310>
print('name:{},age:{},color:{}'.format(jelly.name,jelly.age,jelly.color)) # name:果冻,age:seven months,color:white
- _del_
语法:_del_(self)
用途:析构器,当一个实例被销毁的时候【通过del 对象名进行销毁】调用的方法,一般当主程序执行完时也会调用该方法销毁对象
小例子:
class Dog():
length = 50
def __init__(self,name,age,color):
self.name = name
self.age = age
self.color = color
def __int__(self):
return self.length
def __str__(self):
return '我是一直健健康康的小比熊~我的名字叫%s我今年%s了,你喜欢我嘛(o^^o)'%(self.name,self.age)
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white')
del jelly # 执行销毁时调用__del__,会打印 拜拜啦,我要去睡觉觉了,销毁后再次调用对象则会报错
print(jelly) # NameError: name 'jelly' is not defined
运算符和操作符
算数运算符【+、-、、/、%、*】self+other的情况
- _add_
语法:_add_(self, other)
用途:当对象之间进行加法运算时,程序会自动调用类中的_add_函数,如果没有则报错 - _sub_
语法:_sub_(self, other)
用途:当对象之间进行减法运算时,程序会自动调用类中的_sub_函数,如果没有则报错 - _mul_
语法:_mul_(self, other)
用途:当对象之间进行乘法运算时,程序会自动调用类中的_mul_函数,如果没有则报错 - _truediv_
语法:_truediv_(self,other)【/】
用途:当对象之间进行除法运算时,程序会自动调用类中的_truediv_函数,如果没有则报错 - _floordiv_
语法:_floordiv_(self,other)【//】
用途:当对象之间进行整除运算时,程序会自动调用类中的_floordiv_函数,如果没有则报错 - _mod_
语法:_mod(self, other):
用途:当对象之间进行取余运算时,程序会自动调用类中的_mod_函数,如果没有则报错
-_pow_
语法:_pow(self, power, modulo=None):
用途:当对象进行指数法运算时,程序会自动调用类中的_pow_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
def __add__(self, other):
if isinstance(other,Dog):
return [self,other]
elif isinstance(other,list):
other.append(self)
return other
else:
return '不同种,不能一起养'
def __sub__(self, other):
return '啊哦,%s和%s闹矛盾了,不要一起玩了'%(self , other)
def __mul__(self, other):
return '啊哈,%s和%s终于在一起啦'%(self , other)
def __truediv__(self, other):
return '这是除法'
def __floordiv__(self, other):
return '这是整除'
def __mod__(self, other):
return '这是取余'
def __pow__(self, power, modulo=None):
return '这是指数'
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
hotpot = Dog('火锅','6个月了','black',10)
harry = Dog('哈瑞','3个月了','yello',3)
dogs = jelly + hotpot
print(harry + dogs) # [<博客练习.tmp.Dog object at 0x7fad9809d310>, <博客练习.tmp.Dog object at 0x7fad9805cac0>, <博客练习.tmp.Dog object at 0x7fad9805c820>]
print(jelly-hotpot) # 啊哦,果冻和火锅闹矛盾了,不要一起玩了
print(jelly*hotpot) # 啊哈,果冻和火锅终于在一起啦
print(jelly/hotpot) # 这是除法
print(jelly//hotpot) # 这是整除
print(jelly%hotpot) # 这是取余
print(jelly**int(hotpot)) # 这是指数
'''
如果没有魔法函数的报错信息:
TypeError: unsupported operand type(s) for +: 'Dog' and 'Dog'
'''
位运算【&、|、^、~、<<、>>】
- _and_
语法:
用途:当对象进行&运算时,程序会自动调用类中的_and_函数,如果没有则报错 - _or_
语法:
用途:当对象进行|运算时,程序会自动调用类中的_or_函数,如果没有则报错 - _xor_
语法:
用途:当对象进行^运算时,程序会自动调用类中的_xor_函数,如果没有则报错 - _invert_
语法:_invert(self)
用途:当对象进行~运算时,程序会自动调用类中的_invert函数,如果没有则报错 - _lshift_
语法:_lshift_(self, other)
用途:当对象进行<<运算时,程序会自动调用类中的_lshift_函数,如果没有则报错 - _rshift_
语法:_\rshift_(self, other)
用途:当对象进行>>运算时,程序会自动调用类中的_rshift_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
def __and__(self, other):
return '%s&%s'%(self,other)
def __or__(self, other):
return '%s|%s'%(self,other)
def __xor__(self, other):
return '%s^%s'%(self,other)
def __invert__(self):
return '%s~取反'%self
def __lshift__(self, other):
return '%s左移动%s位'%(self, other)
def __rshift__(self, other):
return '%s右移动%s位'%(self, other)
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
hotpot = Dog('火锅','6个月了','black',10)
print(jelly&hotpot) # 果冻&火锅
print(jelly|hotpot) # 果冻|火锅
print(jelly^hotpot) # 果冻^火锅
print(~hotpot) # 火锅~取反
print(jelly>>2) # 果冻右移动2位
print(jelly<<2) # 果冻左移动2位
比较运算符【>、>=、<、<=、==、!=】
- _gt_
语法:_gt_(self, other)
用途:当对象之间进行>比较运算时,程序会自动调用类中的_gt_函数,如果没有则报错 - _ge_
语法:_ge_(self, other)
用途:当对象之间进行>=比较运算时,程序会自动调用类中的_ge_函数,如果没有则报错 - _lt_
语法:_lt_(self, other)
用途:当对象之间进行<比较运算时,程序会自动调用类中的_lt_函数,如果没有则报错 - _le_
语法:_le_(self, other)
用途:当对象之间进行<=比较运算时,程序会自动调用类中的_le_函数,如果没有则报错 - _eq_
语法:_eq_(self, other)
用途:当对象之间进行==比较运算时,程序会自动调用类中的_eq_函数,如果没有则报错 - _ne_
语法:_ne_(self, other)
用途:当对象之间进行!=比较运算时,程序会自动调用类中的_ne_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
'''比较运算符'''
def __gt__(self, other):
return '%s大于%s'%(self, other)
def __ge__(self, other):
return '%s大于等于%s' % (self, other)
def __lt__(self, other):
return '%s小于%s' % (self, other)
def __le__(self, other):
return '%s小于等于%s' % (self, other)
def __eq__(self, other):
return '%s等于%s' % (self, other)
def __ne__(self, other):
return '%s不等于%s' % (self, other)
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
hotpot = Dog('火锅','6个月了','black',10)
print(jelly > hotpot) # 果冻大于火锅
print(jelly >= hotpot) # 果冻大于等于火锅
print(jelly < hotpot) # 果冻小于火锅
print(jelly <= hotpot) # 果冻小于等于火锅
print(jelly == hotpot) # 果冻等于火锅
print(jelly != hotpot) # 果冻不等于火锅
正负运算符
- _pos_
语法:_pos_(self)
用途:当对象使用+表示为正数时,程序会自动调用类中的_pos_函数,如果没有则报错 - _neg_
语法:_neg_(self)
用途:当对象使用-表示为负数时,程序会自动调用类中的_neg_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
'''正负运算符'''
def __pos__(self):
return '我是正数哦'
def __neg__(self):
return '我是负数哦'
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
hotpot = Dog('火锅','6个月了','black',10)
print(+jelly) # 我是正数哦
print(-jelly) # 我是负数哦
复合赋值运算符【+=、-=、=、/=、//=、%=、*=、&=、|=、^=、<<=、>>=】
- _iadd_
语法:_iadd_(self, other)
用途:当对象1+=对象2时,程序会自动调用类中的_iadd_函数,如果没有则报错 - _isub_
语法:_isub_(self, other)
用途:当对象1-=对象2时,程序会自动调用类中的_isub_函数,如果没有则报错 - _imul_
语法:_imul_(self, other)
用途:当对象1*=对象2时,程序会自动调用类中的_imul_函数,如果没有则报错 - _iturediv_
语法:_iturediv_(self, other)
用途:当对象1/=对象2时,程序会自动调用类中的_iturediv_函数,如果没有则报错 - _ifloordiv_
语法:_ifloordiv_(self, other)
用途:当对象1//=对象2时,程序会自动调用类中的_ifloordiv_函数,如果没有则报错 - _imod_
语法:_imod_(self, other)
用途:当对象1%=对象2时,程序会自动调用类中的_imod_函数,如果没有则报错 - _ipow_
语法:_ipow_(self, other)
用途:当对象1**=对象2时,程序会自动调用类中的_ipow_函数,如果没有则报错 - _iand_
语法:_iand_(self, other)
用途:当对象1&=对象2时,程序会自动调用类中的_iand_函数,如果没有则报错 - _ior_
语法:_ior_(self, other)
用途:当对象1|=对象2时,程序会自动调用类中的_ior_函数,如果没有则报错 - _ixor_
语法:_ixor_(self, other)
用途:当对象1^=对象2时,程序会自动调用类中的_ixor_函数,如果没有则报错 - _ilshift_
语法:_ilshift_(self, other)
用途:当对象1<<=对象2时,程序会自动调用类中的_ilshift_函数,如果没有则报错 - _irshift_
语法:_irshift_(self, other)
用途:当对象1>>=对象2时,程序会自动调用类中的_irshift_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
'''复合赋值运算符'''
def __iadd__(self, other):
print('%s加等于%s,%s等于%s加%s'%(self, other,self,self, other))
return self
def __isub__(self, other):
print('%s减等于%s,%s等于%s减%s' % (self, other, self, self, other))
return self
def __imul__(self, other):
print('%s乘等于%s,%s等于%s乘以%s' % (self, other, self, self, other))
return self
def __itruediv__(self, other):
print('%s除等于%s,%s等于%s除以%s' % (self, other, self, self, other))
return self
def __ifloordiv__(self, other):
print('%s等于%s整除%s' % ( self, self, other))
return self
def __imod__(self, other):
print('%s等于%s对%s取余' % (self, self, other))
return self
def __ipow__(self, other):
print( '%s等于%s的%s次方' % (self, self, other))
return self
def __iand__(self, other):
print( '%s等于%s&%s' % (self, self, other))
return self
def __ior__(self, other):
print( '%s等于%s|%s' % (self, self, other))
return self
def __ixor__(self, other):
print( '%s等于%s^%s' % (self, self, other))
return self
def __ilshift__(self, other):
print( '%s等于%s<<%s' % (self, self, other))
return self
def __irshift__(self, other):
print( '%s等于%s>>%s' % (self, self, other))
return self
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
hotpot = Dog('火锅','6个月了','black',10)
jelly += hotpot # 果冻加等于火锅,果冻等于果冻加火锅
jelly -= hotpot # 果冻减等于火锅,果冻等于果冻减火锅
jelly *= hotpot # 果冻乘等于火锅,果冻等于果冻乘以火锅
jelly /= hotpot # 果冻除等于火锅,果冻等于果冻除以火锅
jelly //= hotpot # 果冻等于果冻整除火锅
jelly %= hotpot # 果冻等于果冻对火锅取余
jelly **= hotpot # 果冻等于果冻的火锅次方
jelly &= hotpot # 果冻等于果冻&火锅
jelly |= hotpot # 果冻等于果冻|火锅
jelly ^= hotpot # 果冻等于果冻^火锅
jelly <<= hotpot # 果冻等于果冻<<火锅
jelly >>= hotpot # 果冻等于果冻>>火锅
运算符【+、-、、/、%、*、】
other+self且other类没有实现上面运算符魔法方法的情况,如果other类实现了比如_add_方法则会优先进入other类的_add_方法去执行,other类没有该方法时才会去self类中寻找_radd_方法
- _radd_
语法:_radd_(self, other)
用途:当对象之间进行加法运算时,程序会自动调用类中的_radd_函数,如果没有则报错 - _rsub_
语法:_rsub__(self, other)
用途:当对象之间进行减法运算时,程序会自动调用类中的_rsub_函数,如果没有则报错 - _rmul_
语法:_rmul_(self, other)
用途:当对象之间进行乘法运算时,程序会自动调用类中的_rmul_函数,如果没有则报错 - _rtruediv_
语法:_rtruediv_(self,other)【/】
用途:当对象之间进行除法运算时,程序会自动调用类中的_rtruediv_函数,如果没有则报错 - _rfloordiv_
语法:_rfloordiv_(self,other)【//】
用途:当对象之间进行整除运算时,程序会自动调用类中的_rfloordiv_函数,如果没有则报错 - _rmod_
语法:_rmod_(self, other):
用途:当对象之间进行取余运算时,程序会自动调用类中的_rmod_函数,如果没有则报错 - _rpow_
语法:_rpow_(self, power, modulo=None):
用途:当对象进行指数法运算时,程序会自动调用类中的_rpow_函数,如果没有则报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,lenght):
self.name = name
self.age = age
self.color = color
self.length = lenght
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
def __radd__(self, other):
return '%s+%s'%(other,self)
def __rsub__(self, other):
return '%s-%s' % (other, self)
def __rmul__(self, other):
return '%s*%s' % (other, self)
def __rtruediv__(self, other):
return '%s/%s' % (other, self)
def __rfloordiv__(self, other):
return '%s//%s' % (other, self)
def __rmod__(self, other):
return '{}%{}' .format (other, self)
def __rpow__(self, other):
return '%s**%s' % (other, self)
def __rand__(self, other):
return '%s&%s' % (other, self)
def __ror__(self, other):
return '%s|%s' % (other, self)
def __rxor__(self, other):
return '%s^%s' % (other, self)
def __rlshift__(self, other):
return '%s<<%s' % (other, self)
def __rrshift__(self, other):
return '%s>>%s' % (other, self)
class Cat:
def __init__(self,name,age,color,length):
self.name = name
self.age = age
self.color = color
self.length = length
def __str__(self):
return self.name
# def __add__(self, other):
# print('%s加%s'%(self,other))
from 博客练习.tmp import Dog,Cat
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
jeck = Cat('杰克','3个月了','hui',15)
print(jeck + jelly) # 杰克+果冻
print(jeck - jelly) # 杰克-果冻
print(jeck * jelly) # 杰克*果冻
print(jeck / jelly) # 杰克/果冻
print(jeck // jelly) # 杰克//果冻
print(jeck % jelly) # 杰克%果冻
print(jeck ** jelly) # 杰克**果冻
print(jeck & jelly) # 杰克&果冻
print(jeck | jelly) # 杰克|果冻
print(jeck ^ jelly) # 杰克^果冻
print(jeck << jelly) # 杰克<<果冻
print(jeck >> jelly) # 杰克>>果冻
数据类型转换【int、float、bool、str、complex】
- _int_
语法:_int_(self)
用途:当我们使用int()函数去调用类对象时,程序会自动去类中找_int_函数,如果找到将该函数的返回值返回给int函数,如果没有找到则会报错 - _float_
语法:_float_(self)
用途:当我们使用float()函数去调用类对象时,程序会自动去类中找_float_函数,如果找到将该函数的返回值返回给float函数,如果没有找到则会报错 - _bool_
语法:_bool_(self)
用途:当我们使用bool()函数去调用类对象时,程序会自动去类中找_bool_函数,如果找到将该函数的返回值返回给bool函数,如果没有找到则会报错 - _str_
语法:_str_(self)
用途:当我们直接print对象或者使用str()函数时,程序会去类中找_str_函数,如果有则打印该函数的返回值,如果没有则返回对象地址 - _complex_
语法:_complex_(self)
用途:当我们使用complex()函数去调用类对象时,程序会自动去类中找_complex_函数,如果找到将该函数的返回值返回给complex函数,如果没有找到则会报错
小例子:
class Dog():
length = 50
# 胖了多少斤
set_height = -1
# 每天吃多少克狗粮
eat = 45.5
# 会听口令坐下吗
sit = True
def __init__(self,name,age,color):
self.name = name
self.age = age
self.color = color
def __del__(self):
print('拜拜啦,我要去睡觉觉了')
def __int__(self):
return self.length
def __float__(self):
return self.eat
def __bool__(self):
return self.sit
def __str__(self):
return '我是一直健健康康的小比熊~我的名字叫%s我今年%s了,你喜欢我嘛(o^^o)'%(self.name,self.age)
def __complex__(self):
return '5+2j'
from 博客练习.tmp import Dog
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white')
'''
指定__int__、__float__、__bool__、__str__、__complex__函数前
print(int(jelly)) # TypeError: int() argument must be a string, a bytes-like object or a number, not 'Dog'
print(float(jelly)) # TypeError: float() argument must be a string or a number, not 'Dog'
print(bool(jelly)) # TypeError: complex() first argument must be a string or a number, not 'Dog'
print(jelly) # <博客练习.tmp.Dog object at 0x7fd7b000d310>
print(complex(jelly)) # TypeError: complex() first argument must be a string or a number, not 'Dog'
'''
'''
指定类型转换的魔法方法后
'''
print(int(jelly)) # 50
print(float(jelly)) # 45.5
print(bool(jelly)) # True
print(jelly) # 我是一直健健康康的小比熊~我的名字叫果冻我今年7个月了了,你喜欢我嘛(o^^o)
print(str(jelly)) # 我是一直健健康康的小比熊~我的名字叫果冻我今年7个月了了,你喜欢我嘛(o^^o)
print(complex(jelly)) # (5+2j)
内置函数
当调用内置函数,参数为对象时,程序会自动调用函数定义时的魔法方法,如果有则返回魔法方法的返回值。如果没有则报错,结合https://www.jianshu.com/p/c71d04f9a45a这篇博客一起看
- _abs_
- _hash_
- _len_
- _format_
- _iter_
- _next_
- _repr_
- _delattr_
- _getattr_
- _round_
- _setattr_
- _dir_
- _divmod_
- _rdivmod_
- _call_
小例子:
类定义部分:
from typing import Iterable
class Dog():
length = 50
# 胖了多少斤
set_height = -1
def __init__(self,name,age,color,length):
self.name = name
self.age = age
self.color = color
self.length = length
def __del__(self):
# print('拜拜啦,我要去睡觉觉了')
pass
def __str__(self):
return self.length
'''内置函数'''
def __abs__(self):
return abs(self.set_height)
# '叮咚,调用了hash函数,求对象的哈希值'
def __hash__(self):
return 23
# '叮咚,调用了len函数,求对象的长度'
def __len__(self):
return 37
def __format__(self, format_spec):
return format_spec.replace('{}','叮咚,调用了format函数,使用对象指定的格式化方式格式化字符串')
def __iter__(self):
return iter('叮咚,调用了iter函数,将对象转换为迭代器')
def __next__(self):
return '叮咚,调用了next函数,取迭代器的下一个元素'
def __repr__(self):
return '叮咚,调用了repr函数,返回对象的ascii表示'
# item为属性
def __delattr__(self, item):
print('叮咚,调用了delattr函数,删除对象属性')
# item为属性
def __getattr__(self, item):
print('叮咚,调用了getattr函数,获取对象属性')
def __round__(self, n=None):
return '叮咚,调用了round函数,获取对象的四舍六入'
# key为属性名,value为属性值
def __setattr__(self, key, value):
print('叮咚,调用了setattr函数,给属性赋值')
def __dir__(self) -> Iterable[str]:
return iter(['果冻','jelly','叮咚,调用了dir函数,获取对象的所有变量方法和定义'])
def __divmod__(self, other):
return self-other
def __rdivmod__(self, other):
return '叮咚,调用了rdivmod函数,函数返回的结果为(y//x,y%x)的元组'
# # 对应callable内置函数
def __call__(self, *args, **kwargs):
return '叮咚,调用了callable函数,使对象能像函数一样调用'
调用部分:
from 博客练习.tmp import Dog,Cat
if __name__ == '__main__':
jelly = Dog('果冻','7个月了','white',15)
huoguo = Cat('杰瑞','3个月了','black',20)
print(abs(jelly)) # 1
print(hash(jelly)) # 23
print(len(jelly)) # 37
print(format(jelly,'请说:{}')) # 请说:叮咚,调用了format函数,使用对象指定的格式化方式格式化字符串
print(iter(jelly)) # <str_iterator object at 0x7fd880174700>
print(next(jelly)) # 叮咚,调用了next函数,取迭代器的下一个元素
print(repr(jelly)) # 叮咚,调用了repr函数,返回对象的ascii表示
delattr(jelly,'length') # 叮咚,调用了delattr函数,删除对象属性
print(getattr(jelly,'luo')) # 叮咚,调用了getattr函数,获取对象属性
print(round(jelly)) # 叮咚,调用了round函数,获取对象的四舍六入
print(setattr(jelly,'length',88)) # 叮咚,调用了setattr函数,给属性赋值
print(dir(jelly)) # ['jelly', '叮咚,调用了dir函数,获取对象的所有变量方法和定义', '果冻']
print(callable(jelly)) # True
上下文管理器
- _enter_:表示上文方法,需要返回一个操作文件的对象
- _exit_:表示下文方法,with语句执行完会自动执行,即使出现异常也会执行该方法
例子:
import time
class File:
def __init__(self,file_name,file_model):
self.file_name = file_name
self.file_model = file_model
# 上文方法
def __enter__(self):
print('这是上文')
self.file = open(self.file_name,self.file_model)
return self.file
# 下文方法
def __exit__(self, exc_type, exc_val, exc_tb):
print('这是下文')
self.file.close()
if __name__ == '__main__':
with File('test.txt','r') as f:
while True:
line = f.readline()
time.sleep(5)
if not line:
break
print(line)
持续更新中……