python双下方法有哪些,怎样应用的
Admin 2022-10-18 群英技术资讯 248 次浏览
+
号,在字符串运算中却变成拼接功能,如'ab' + 'cd'
结果为abcd
;而*
号变成了重复功能,如'ab' * 2
结果为abab
。为什么某些对象print
能输出数据,而print
自定义的类对象却输出一堆看不懂的代码<__main__.MyCls object at 0x105732250>
。
不是因为系统做了特殊定制,而是 Python 中有一类特殊的方法,在某些特定的场合会自动调用。如,在字符串类str
中定义了__add__
方法后,当代码遇到字符串相加'ab' + 'cd'
时,就会自动调用__add__
方法完成字符串拼接。
因为这类特殊方法的方法名都是以双下划线开始和结束,所以又被称为双下方法。
Python 中的双下方法很多,今天我们对它做个详解。
Python中的双下方法
__init__
的方法是很多人接触的第一个双下方法
。
classA: def__init__(self,a): self.a=a
当调用A()
实例化对象的时候,__init__
方法会被自动调用,完成对象的初始化。
在类中定义运算符相关的双下方法
,可以直接在类对象上做加减乘除、比较等操作。
这里,定义一个尺子类Rule
,它包含一个属性r_len
代表尺子的长度。
classRule: def__init__(self,r_len): self.r_len=r_len
如果想按照尺子的长度对不同的尺子做比较,需要在Rule
类中定义比较运算符。
classRule: def__init__(self,r_len): self.r_len=r_len #<运算符 def__lt__(self,other): returnself.r_len<other.r_len #<=运算符 def__le__(self,other): returnself.r_len<=other.r_len #>运算符 def__gt__(self,other): returnself.r_len>other.r_len #>=运算符 def__ge__(self,other): returnself.r_len>=other.r_len
这里定义了<
、<=
、>
和>=
四个比较运算符,这样就可以用下面的代码比较Rule
对象了。
rule1=Rule(10) rule2=Rule(5) print(rule1>rule2)#True print(rule1>=rule2)#True print(rule1<rule2)#False print(rule1<=rule2)#False
当用>
比较rule1
和rule2
的时候,rule1
对象会自动调用__gt__
方法,并将rule2
对象传给other
参数,完成比较。
下面是比较运算符的双下方法
比较运算符双下方法
可以支持类对象加减乘除。
def__add__(self,other): returnRule(self.r_len+other.r_len)
这里定义了__add__
方法,对应的是+
运算符,他会把两个尺子的长度相加,并生成新的尺子。
rule1=Rule(10) rule2=Rule(5) rule3=rule1+rule2
下面是算术运算符的双下方法
它支持其他类型的变量与Rule
类相加。以__radd__
方法为例
def__radd__(self,other): returnself.r_len+other
rule1=Rule(10) rule2=10+rule1
程序执行10 + rule1
时,会尝试调用int
类的__add__
但int
类类没有定义与Rule
类对象相加的方法,所以程序会调用+
号右边对象rule1
的__radd__
方法,并把10
传给other
参数。
所以这种运算符又叫右加运算符。它所支持的运算符与上面的算术运算符一样,方法名前加r
即可。
增量赋值运算符是+=
、-=
、*=
、/=
等。
def__iadd__(self,other): self.r_len+=other returnself
rule1=Rule(10) rule1+=5
除了__divmod__
方法,其他的跟算数运算符一样,方面名前都加i。
这部分支持按二进制进行取反、移位和与或非等运算。由于Rule
类不涉及位运算,所以我们换一个例子。
定义二进制字符串的类BinStr
,包含bin_str
属性,表示二进制字符串。
classBinStr: def__init__(self,bin_str): self.bin_str=bin_str
x=BinStr('1010')#创建二进制字符串对象 print(x.bin_str)#1010
给BinStr
定义一个取反运算符~
#~运算符 def__invert__(self): inverted_bin_str=''.join(['1'ifi=='0'else'0'foriinself.bin_str]) returnBinStr(inverted_bin_str)
__invert__
方法中,遍历bin_str
字符串,将每位取反,并返回一个新的BinStr
类对象。
x=BinStr('1011') invert_x=~x print(invert_x.bin_str)#0100
下面是位运算符的双下方法
这部分也支持反向位运算符和增量赋值位运算符,规则跟算数运算符一样,这里就不再赘述。
这部分涉及两个双下方法__repr__
和__format__
,在某些特殊场景,如print
,会自动调用,将对象转成字符串。
还是以BinStr
为例,先写__repr__
方法。
def__repr__(self): decimal=int('0b'+self.bin_str,2) returnf'二进制字符串:{self.bin_str},对应的十进制数字:{decimal}'
x=BinStr('1011') print(x) #输出:二进制字符串:1011,对应的十进制数字:11
当程序执行print(x)
时,会自动调用__repr__
方法,获取对象x
对应的字符串。
再写__format__
方法,它也是将对象格式化为字符串。
def__format__(self,format_spec): returnformat_spec%self.bin_str
print('{0:二进制字符串:%s}'.format(x)) #输出:二进制字符串:1011
当.format
方法的前面字符串里包含0:
时,就会自动调用__format__
方法,并将字符串传给format_spec
参数。
调用int(obj)
、float(obj)
等方法,可以将对象转成相对应数据类型的数据。
def__int__(self): returnint('0b'+self.bin_str,2)
x=BinStr('1011') print(int(x))
当调用int(x)
时,会自动调用__int__
方法,将二进制字符串转成十进制数字。
数值转换除了上面的两个外,还有__abs__
、__bool__
、__complex__
、__hash__
、__index__
和__str__
。
__str__
和__repr__
一样,在print
时都会被自动调用,但__str__
优先级更高。
这部分可以像集合那样,定义对象长度、获取某个位置元素、切片等方法。
以__len__
和__getitem__
为例
def__len__(self): returnlen(self.bin_str) def__getitem__(self,item): returnself.bin_str[item]
x=BinStr('1011') print(len(x))#4 print(x[0])#1 print(x[0:3])#101
len(x)
会自动调用__len__
返回对象的长度。
通过[]
方式获取对象的元素时,会自动调用__getitem__
方法,并将切片对象传给item
参数,即可以获取单个元素,还可以获取切片。
集合相关的双下方法还包括__setitem__
、__delitem__
和__contains__
。
可以在对象上使用for-in
遍历。
def__iter__(self): self.cur_i=-1 returnself def__next__(self): self.cur_i+=1 ifself.cur_i>=len(self.bin_str): raiseStopIteration()#退出迭代 returnself.bin_str[self.cur_i]
x=BinStr('1011') foriinx: print(i)
当在x
上使用for-in
循环时,会先调用__iter__
方法将游标cur_i
置为初始值-1
,然后不断调用__next__
方法遍历self.bin_str
中的每一位。
这部分还有一个__reversed__
方法用来反转对象。
def__reversed__(self): returnBinStr(''.join(list(reversed(self.bin_str))))
x=BinStr('1011') reversed_x=reversed(x) print(reversed_x) #输出:二进制字符串:1101,对应的十进制数字:13
做 web 开发的朋友,用类相关的双下方法会更多一些。
实例的创建是__new__
和__init__
方法,实例的销毁是__del__
方法。
__new__
的调用早于__init__
,它的作用是创建对象的实例(内存开辟一段空间),而后才将该实例传给__init__
方法,完成实例的初始化。
由于__new__
是类静态方法,因此它可以控制对象的创建,从而实现单例模式。
__del__
方法在实例销毁时,被自动调用,可以用来做一些清理工作和资源释放的工作。
类属性的访问和设置。包括__getattr__
、__getattribute__
、__setattr__
和__delattr__
方法。
__getattr__
和__getattribute__
的区别是,当访问类属性时,无论属性存不存在都会调用__getattribute__
方法,只有当属性不存在时才会调用__getattr__
方法。
控制属性的访问,一般用于把属性的取值控制在合理范围内。包括__get__
、__set__
和__delete__
方法。
classXValidation: def__get__(self,instance,owner): returnself.x def__set__(self,instance,value): if0<=value<=100: self.x=value else: raiseException('x不能小于0,不能大于100') def__delete__(self,instance): print('删除属性') classMyCls: x=XValidation() def__init__(self,n): self.x=n obj=MyCls(10) obj.x=101 print(obj.x)#抛异常:Exception: x不能小于0,不能大于100
上述例子,通过类属性描述符,可以将属性x的取值控制在[0, 100]
之前,防止不合法的取值。
虽然上面介绍的不是所有的双下方法,但也算是绝大多数了。
虽然双下方法里可以编写任意代码,但大家尽量编写与方法要求一样的代码。如,在__add__
方法实现的不是对象相加而是相减,虽然也能运行,但这样会造成很大困惑,不利于代码维护
关于“python双下方法有哪些,怎样应用的”的内容今天就到这,感谢各位的阅读,大家可以动手实际看看,对大家加深理解更有帮助哦。如果想了解更多相关内容的文章,关注我们,群英网络小编每天都会为大家更新不同的知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了matlab xlabel位置的设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
这篇文章主要介绍了python流程控制,文章主要根据python流程控制的相关资料展开全文内容,具有一定的参考解释,需要的小伙伴可以参考一下,希望对你有所帮助
这篇文章主要介绍了python如何删除字符串最后一个字符,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
这篇文章主要为大家介绍了Python常用的内置函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
这篇文章主要介绍了Python学习之名字,作用域,名字空间,紧接上一篇文章内容展开全文,需要的小伙伴可以参考一下,希望对你的学习有所帮助
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008