百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

python中类class的魔法方法(类class python)

off999 2025-05-02 12:51 29 浏览 0 评论

开始介绍之前,我们先看下之前文章我们介绍过的内置类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 = brand
    self.color = color
    self.cost_performance = cost_performance

  def __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__

  1. __str__:当使用print函数打印对象实例或者str函数转换对象实例时,会调用该方法返回的字符串,如果没有该方法会继续找__repr__方法中的字符串信息
  2. __repr__:当使用repr函数打印对象实例时,会调用该方法返回的字符串,如果没有该方法会继续找__str_方法中的字符串信息

举例:

class Car(object):
  def __init__(self,brand,color,cost_performance):
    print('__init__被调用')
    self.brand = brand
    self.color = color
    self.cost_performance = cost_performance
  def __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 = newlist
  def __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] = value
  def __delitem__(self, index):
  	print('使用了__delitem__')
  	del self.newlist[index]
  def __contains__(self, item):
  	print('使用了__contains__')
  	return item in self.newlist
  def __reversed__(self):
  	print('使用了__reversed__')
		return reversed(self.newlist)

对自定义列表对象进行增删改查时,会用到上述魔法方法:

先初始化实例:

mylist1 = MyList([1,2,3,4,5])

1)获取元素个数:

print(f'初始元素个数:{len(mylist1)}')

结果:

使用了__len__
初始元素个数:5

2)获取元素值

print(f'index为1的值:{mylist1[1]}')

结果:

使用了__getitem__
index为1的值:2

3)设置元素值

mylist1[0] = 100
print(f'index为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 == other
  def __le__(self,other:int):
  	print('使用了__getitem__')
  	return self.num <= other
  def __ge__(self, other:int):
  	print('使用了__ge__')
  	return self.num >= other
  def __lt__(self, other:int):
  	print('使用了__lt__')
  	return self.num < other
  def __gt__(self, other:int):
 		print('使用了__gt__')
  	return self.num > other
  def __ne__(self,other:int):
  	print('使用了__ne__')
  	return self.num != other

初始化类,传入数字10,并将对象做比较运算。

newnum = rnum(10)
print(f'newnum.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 + other
  def __sub__(self,other:int):
  	print('使用了__sub__')
  	return self.num - other
  def __mul__(self, other:int):
  	print('使用了__mul__')
  	return self.num * other
  def __floordiv__(self, other:int):
  	print('使用了__floordiv__')
  	return self.num // other
  def __mod__(self,other:int):
  	print('使用了__mod__')
  	return self.num % other
  def __divmod__(self,other:int):
  	print('使用了__divmod__')
  	return divmod(self.num,other)
  def __pow__(self,other:int):
  	print('使用了__pow__')
  	return self.num ** other
  def __lshift__(self,other:int):
  	print('使用了__lshift__')
  	return self.num << other
  def __rshift__(self,other:int):
  	print('使用了__rshift__')
  	return self.num >> other
  def __and__(self,other:int):
  	print('使用了__and__')
  	return self.num & other
  def __or__(self,other:int):
  	print('使用了__or__')
  	return self.num | other
  def __xor__(self,other:int):
  	print('使用了__xor__')
  	return self.num ^ other

初始化类,并计算如下:

1)按数值计算

newnum = rnum(100)
print(f'newnum.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(f'2进制转为10进制数:{int("0b101001",base=2)}')

#0b101001 整体往左移3位变成0b101001000
print(f'2进制转为10进制数:{int("0b101001000",base=2)}')

#0b101001 整体往右移3位变成0b101
print(f'2进制转为10进制数:{int("0b101",base=2)}')

#0b101001 与数字3(0b11) 做&的运算 得到0b000001
print(f'2进制转为10进制数:{int("0b000001",base=2)}')

#0b101001 与数字3(0b11) 做|的运算 得到0b101011
print(f'2进制转为10进制数:{int("0b101011",base=2)}')

#0b101001 与数字3(0b000011) 做^的运算 得到0b101010
print(f'2进制转为10进制数:{int("0b101010",base=2)}')

结果:跟上面按位运算的结果一致

数字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 = brand
  	self.color = color
  	self.cost_performance = cost_performance
  def __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] = value
  def __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'}


共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习和关注,谢谢大家。

相关推荐

安全教育登录入口平台(安全教育登录入口平台官网)

122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...

大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)

大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...

谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)

要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...

2026-02-04 09:03 off999

电信宽带测速官网入口(电信宽带测速官网入口app)

这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...

植物大战僵尸95版手机下载(植物大战僵尸95 版下载)

1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...

免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)

1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...

2025世界杯赛程表(2025世界杯在哪个国家)

2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...

下载搜狐视频电视剧(搜狐电视剧下载安装)

搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...

pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
永久免费听歌网站(丫丫音乐网)

可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...

音乐格式转换mp3软件(音乐格式转换器免费版)

有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...

电子书txt下载(免费的最全的小说阅读器)

1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...

最好免费观看高清电影(播放免费的最好看的电影)

在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...

孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)

要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...

取消回复欢迎 发表评论: