素材网站的图可以做海报吗,谷歌优化工具,wordpress给公司建站,专业开发网站公司开始介绍之前#xff0c;我们先看下之前文章我们介绍过的内置类merryview的一些方法#xff0c;如下图所示#xff1a; 有很多双下划线开始和结束的method#xff0c;这么多method是做啥子用的呢#xff1f; 其实这些方法就是我们常说的魔法方法#xff0c;也是python中的…
开始介绍之前我们先看下之前文章我们介绍过的内置类merryview的一些方法如下图所示 有很多双下划线开始和结束的method这么多method是做啥子用的呢 其实这些方法就是我们常说的魔法方法也是python中的特殊方法。它们以双下划线 __ 开始和结束这些方法为 Python 类提供了丰富的功能。
以下开始介绍下常见的魔法方法
1 构造方法
构造方法有__new__ __init__ __del__
__new__如果设置了该方法当我们定义类的实例时该方法会被第一个调用而不是先调用__init__方法。该方法需要返回一个类的实例。
__init__: 初始化类的实例属性并可在该方法中定义其他一些属性或者调用其他函数等作为初始化的功能。
__del__: 当类实例对象销毁时会自动调用该方法。
举例定义一个类并做类的实例化
class Car(object):def __init__(self,brand,color,cost_performance):print(__init__被调用)self.brand brandself.color colorself.cost_performance cost_performancedef __new__(cls, *args, **kwargs):print(__new__被调用)def __del__(self):print(__del__被调用)
实例化类
car_ins Car(BYD,black,high)
print(car_ins.brand)
当执行时发现报错如下只有__new__方法被调用了而没有调用__init__所以在打印实例属性时报错。 原因是__new__方法中没有返回对象实例。
我们在__new__方法中添加如下一行代码super().__new__(cls)
def __new__(cls, *args, **kwargs):print(__new__被调用)return super().__new__(cls)
再次实例化类的时候
car_ins Car(BYD,black,high)
print(car_ins.brand)
打印结果如下
__new__被调用
__init__被调用
BYD
__del__被调用
解释增加的这一行super().__new__(cls)作用就是调用基类object创建一个实例并返回有了实例然后再调用__init__ 方法做初始化。当程序执行完成后实例对象的内存会被释放然后自动调用__del__方法。
2 类的表示方法
类的表示方法主要有__repr__ __str__
__str__当使用print函数打印对象实例或者str函数转换对象实例时会调用该方法返回的字符串如果没有该方法会继续找__repr__方法中的字符串信息__repr__当使用repr函数打印对象实例时会调用该方法返回的字符串如果没有该方法会继续找__str_方法中的字符串信息
举例
class Car(object):def __init__(self,brand,color,cost_performance):print(__init__被调用)self.brand brandself.color colorself.cost_performance cost_performancedef __str__(self):print(__str__被调用)return 我是Car类def __repr__(self):print(__repr__被调用)return 我是Car类
类实例化后打印下类实例
car_ins Car(BYD,black,high)
print(car_ins)
print(str(car_ins))
print(repr(car_ins))
结果
__str__被调用
我是Car类
__str__被调用
我是Car类
__repr__被调用
我是Car类
3 上下文管理器方法
通过定义一个类,并实现__enter__()和__exit__()方法,那么这个类就可以被称为上下文管理器也就可以使用with as的语句。
__enter__()方法:返回一个值,可以将它赋值给with...as后面的对象。
__exit__()方法: with...as 语句退出或者发送异常时会执行这个方法。
比如之前我们的文章讲到open函数我们经常会用到上下文管理器
with open(test.txt,r) as fd:content fd.readlines ()
4 可迭代对象和迭代器方法
方法有 __iter__ __next__
可迭代对象指python中可以用来迭代支持for循环的对象比如常见的列表/元组/字典/字符串等这些对象中都会定义__iter__魔法方法。迭代器指可以帮助我们迭代其他对象的一种对象。这类对象会定义__next__魔法方法可通过next()函数获取迭代的结果。
可迭代对象不一定是迭代器但迭代器肯定是可迭代对象。因为迭代器要求必须同时实现__iter__方法和__next__方法 而一旦实现了__iter__方法就必然是一个可迭代对象。但是反过来则不成立可迭代对象可以不是迭代器。
1判断对象是可迭代对象和迭代器
在python模块中先导入Iterable和Iterator。
from typing import Iterable,Iterator
或者
from collections.abc import Iterable,Iterator
通过isinstance(Object, Iterable)可判断一个对象是否是可迭代对象
通过isinstance(Object, Iterator)可判断一个对象是否是迭代器
2常见的列表等是可迭代对象但不是迭代器。
#定义一个列表
listA [1,4,3,2]
print(f列表是否是迭代对象 {isinstance(listA,Iterable)})
print(f列表是否是迭代器 {isinstance(listA,Iterator)})
#结果
列表是否是迭代对象 True
列表是否是迭代器 False
python安装好后有个自带的模块builtins.py找到定义的list类会发现该类中定义了__iter__方法没有定义__next__方法。
class list(object):Built-in mutable sequence.If no argument is given, the constructor creates a new empty list.The argument must be an iterable if specified.def append(self, *args, **kwargs): # real signature unknown Append object to the end.....def __iter__(self, *args, **kwargs): # real signature unknown Implement iter(self). pass
使用next()执行列表会报错列表不是一个迭代器。
next(listA)
#会报错如下
Traceback (most recent call last):
File test.py, line 9, in module
next(listA)
TypeError: list object is not an iterator
3使用iter()将可迭代对象转换为迭代器
还是以上面的列表举例使用iter()将列表转换为迭代器。
list_iter iter(listA)
print(f列表使用iter()后是否是迭代对象 {isinstance(list_iter,Iterable)})
print(f列表使用iter()是否是迭代器 {isinstance(list_iter,Iterator)})
#打印结果
列表使用iter()后是否是迭代对象 True
列表使用iter()是否是迭代器 True
5 容器方法
容器方法主要有__len__ __getitem__ __setitem__ __delitem__ __contains__ __reversed__
__len__(self ): 获取容器中元素的数量配合len() 函数使用。__getitem__(self, index): 获取容器中的元素值index表示容器中的索引。__setitem__(self, index, value): 设置容器中的元素值index表示容器中的索引value表示要设置的值。__delitem__(self, index): 删除容器中的元素index表示容器中的索引。__contains__(self, item): 判断容器中是否包含某个元素使用in 判断。__reversed__(self): 当使用reversed() 内建函数会调用该方法定义为返回一个反转之后的序列。
举例自定义一个列表对象并初始化一个传入的列表
class MyList(object):def __init__(self,newlist):self.newlist newlistdef __len__(self):print(使用了__len__)return len(self.newlist)def __getitem__(self,index):print(使用了__getitem__)return self.newlist[index]def __setitem__(self, index, value):print(使用了__setitem__)self.newlist[index] valuedef __delitem__(self, index):print(使用了__delitem__)del self.newlist[index]def __contains__(self, item):print(使用了__contains__)return item in self.newlistdef __reversed__(self):print(使用了__reversed__)return reversed(self.newlist)
对自定义列表对象进行增删改查时会用到上述魔法方法:
先初始化实例
mylist1 MyList([1,2,3,4,5])
1获取元素个数
print(f初始元素个数{len(mylist1)})
结果
使用了__len__
初始元素个数5
2获取元素值
print(findex为1的值{mylist1[1]})
结果
使用了__getitem__
index为1的值2
3设置元素值
mylist1[0] 100
print(findex为0的值{mylist1[0]})
结果
使用了__setitem__
使用了__getitem__
index为0的值100
4删除元素的值
del mylist1[-1]
print(f删除最后一个元素后列表为{list(mylist1)})
结果
使用了__delitem__
使用了__len__
使用了__getitem__
使用了__getitem__
使用了__getitem__
使用了__getitem__
使用了__getitem__
删除最后一个元素后列表为[100, 2, 3, 4]
5判断是否包含某个元素
print(f判断数字2是否在列表内{2 in mylist1})
结果
使用了__contains__
判断数字2是否在列表内True
6反转序列
print(list(reversed(mylist1)))
结果
使用了__reversed__
[4, 3, 2, 100]
6 比较方法
比较方法主要有__eq__ __lt__ __le__ __gt__ __ge__ __ne__
__eq__(self, other):定义等于操作符()的行为。__ne__(self, other):定义不等于操作符(!)的行为。__lt__(self, other):定义小于操作符()的行为。__gt__(self, other):定义大于操作符()的行为。__le__(self, other):定义小于等于操作符()的行为。__ge__(self, other):定义大于等于操作符()的行为。
举例定义一个类初始化时随机生成一个整数。
import random
class rnum(object):def __init__(self,num):self.num random.randint(0,num)def __eq__(self,other:int):print(使用了__eq__)return self.num otherdef __le__(self,other:int):print(使用了__getitem__)return self.num otherdef __ge__(self, other:int):print(使用了__ge__)return self.num otherdef __lt__(self, other:int):print(使用了__lt__)return self.num otherdef __gt__(self, other:int):print(使用了__gt__)return self.num otherdef __ne__(self,other:int):print(使用了__ne__)return self.num ! other
初始化类传入数字10并将对象做比较运算。
newnum rnum(10)
print(fnewnum.num {newnum.num})
#比较对象值的数字7的大小
print(f判断 {newnum 7})
print(f判断 {newnum 7})
print(f判断 {newnum 7})
print(f判断 {newnum 7})
print(f判断 {newnum 7})
print(f判断! {newnum ! 7})
#结果
newnum.num 1
使用了__eq__
判断 False
使用了__ge__
判断 False
使用了__ge__
判断 False
使用了__lt__
判断 True
使用了__gt__
判断 False
使用了__ne__
判断! True
7 算术方法
常用到的算术方法如下
__add__(self, other)实现加法操作。
__sub__(self, other)实现减法-操作。
__mul__(self, other)实现乘法*操作。
__floordiv__(self, other)实现使用//操作符的整数除法。
__div__(self, other)实现使用/操作符的除法。
__mod__(self, other)实现%取余操作。
__divmod__(self, other)实现 divmod 内建函数。__pow__实现冥运算**操作
__lshift__(self, other)实现左移位运算符。
__rshift__(self, other)实现右移位运算符。
__and__(self, other)实现按位与运算符。
__or__(self, other)实现按位或运算符|。
__xor__(self, other)实现按位异或运算符^。
举例定义一个类初始化时随机生成一个整数。
import random
class rnum(object):def __init__(self,num):self.num random.randint(0,num)def __add__(self,other:int):print(使用了__add__)return self.num otherdef __sub__(self,other:int):print(使用了__sub__)return self.num - otherdef __mul__(self, other:int):print(使用了__mul__)return self.num * otherdef __floordiv__(self, other:int):print(使用了__floordiv__)return self.num // otherdef __mod__(self,other:int):print(使用了__mod__)return self.num % otherdef __divmod__(self,other:int):print(使用了__divmod__)return divmod(self.num,other)def __pow__(self,other:int):print(使用了__pow__)return self.num ** otherdef __lshift__(self,other:int):print(使用了__lshift__)return self.num otherdef __rshift__(self,other:int):print(使用了__rshift__)return self.num otherdef __and__(self,other:int):print(使用了__and__)return self.num otherdef __or__(self,other:int):print(使用了__or__)return self.num | otherdef __xor__(self,other:int):print(使用了__xor__)return self.num ^ other
初始化类并计算如下
1按数值计算
newnum rnum(100)
print(fnewnum.num {newnum.num})
print(f加法 {newnum 3})
print(f减法 {newnum - 3})
print(f乘法 {newnum * 3})
print(f//除法 {newnum // 3})
print(f计算余数 {newnum % 3})
print(f计算商和余数 {divmod(newnum,3)})
print(f计算冥次 {newnum ** 3})
#结果
newnum.num 41
使用了__add__
加法 44
使用了__sub__
减法 38
使用了__mul__
乘法 123
使用了__floordiv__
//除法 13
使用了__mod__
计算余数 2
使用了__divmod__
计算商和余数 (13, 2)
使用了__pow__
计算冥次 68921
2按位进行计算指转换为2进制后的一些计算
print(f计算左移 {newnum 3})
print(f计算右移 {newnum 3})
print(f计算位与 {newnum 3})
print(f计算位或 {newnum | 3})
print(f计算位异或^ {newnum ^ 3})
#结果
使用了__lshift__
计算左移 328
使用了__rshift__
计算右移 5
使用了__and__
计算位与 1
使用了__or__
计算位或 43
使用了__xor__
计算位异或^ 42
解释按位计算的示例
print(f数字41的2进制数{bin(41)})
print(f2进制转为10进制数{int(0b101001,base2)})#0b101001 整体往左移3位变成0b101001000
print(f2进制转为10进制数{int(0b101001000,base2)})#0b101001 整体往右移3位变成0b101
print(f2进制转为10进制数{int(0b101,base2)})#0b101001 与数字30b11 做的运算 得到0b000001
print(f2进制转为10进制数{int(0b000001,base2)})#0b101001 与数字30b11 做|的运算 得到0b101011
print(f2进制转为10进制数{int(0b101011,base2)})#0b101001 与数字30b000011 做^的运算 得到0b101010
print(f2进制转为10进制数{int(0b101010,base2)})
结果跟上面按位运算的结果一致
数字41的2进制数:0b101001
2进制转为10进制数:41
2进制转为10进制数:328
2进制转为10进制数:5
2进制转为10进制数:1
2进制转为10进制数:43
2进制转为10进制数:42
补充知识
按位左移将一个数的各二进制位全部左移若干位右边多出的位将用0填充。按位右移将一个数的各二进制位全部右移若干位左边多出的位将用0填充。按位与只有当两个对应位都为1时结果才为1否则结果为0按位或只要有一个对应位为1时结果就为1都为0时结果为0按位异或相同为0不同为1如果两个比较的位相同则结果为0如果不同则结果为1。
8 属性方法
关于属性相关的有以下方法
__dir__(self)定义对类的实例调用 dir() 时的行为返回一个属性列表。
__getattr__(self,name)当用户试图访问一个不存在的属性时会调用该方法。
__setattr__(self,name,value)自定义某个属性的赋值时调用该方法。
__delattr__(self,name)删除某个属性时调用该方法。
举例定义一个类以及上面的方法
class Car(object):def __init__(self,brand,color,cost_performance):print(__init__被调用)self.brand brandself.color colorself.cost_performance cost_performancedef __dir__(self):print(__dir__被调用)return [brand,color,cost_performance]def __getattr__(self, name):print(__getattr__被调用)return self.__dict__.get(name)def __setattr__(self,name,value):print(__setattr__被调用)self.__dict__[name] valuedef __delattr__(self,name):print(__delattr__被调用)del self.__dict__[name]
类实例化
car_ins Car(BYD,black,high)
1返回实例的属性列表
print(dir(car_ins))
结果
__dir__被调用
[brand, color, cost_performance]
2返回实例的属性字典
print(car_ins.__dict__)
结果
{brand: BYD, color: black, cost_performance: high}
3获取某个属性
print(car_ins.other)
结果因为没有该属性所以返回为None
__getattr__被调用
None
4设置属性
car_ins.other xxx
print(car_ins.__dict__)
结果
__setattr__被调用
{brand: BYD, color: black, cost_performance: high, other: xxx}
5删除属性
del car_ins.other
print(car_ins.__dict__)
结果
__delattr__被调用
{brand: BYD, color: black, cost_performance: high} 共勉 东汉·班固《汉书·枚乘传》“泰山之管穿石单极之绠断干。水非石之钻索非木之锯渐靡使之然也。”
-----指水滴不断地滴可以滴穿石头
-----比喻坚持不懈集细微的力量也能成就难能的功劳。
----感谢读者的阅读和学习和关注谢谢大家。