加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

在Python中实现双倍下方方法的指南及示例

发布时间:2023-10-17 11:12:29 所属栏目:语言 来源:
导读:这篇文章主要介绍了“python双下方法有哪些,怎样应用的”相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python双下方法有哪些,怎样应用的文章都会有所收获,下面我们一起

这篇文章主要介绍了“python双下方法有哪些,怎样应用的”相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python双下方法有哪些,怎样应用的文章都会有所收获,下面我们一起来看看吧。

大家在写 Python 代码的时候有没有这样的疑问。为什么数学中的+号,在字符串运算中却变成拼接功能,如'ab' + 'cd'结果为abcd;而*号变成了重复功能,如'ab' * 2结果为abab。

为什么某些对象print能输出数据,而print自定义的类对象却输出一堆看不懂的代码<__main__.MyCls object at 0x105732250>。

不是因为系统做了特殊定制,而是 Python 中有一类特殊的方法,在某些特定的场合会自动调用。如,在字符串类str中定义了__add__方法后,当代码遇到字符串相加'ab' + 'cd'时,就会自动调用__add__方法完成字符串拼接。

因为这类特殊方法的方法名都是以双下划线开始和结束,所以又被称为双下方法。

Python 中的双下方法很多,今天我们对它做个详解。

1. init方法

__init__的方法是很多人接触的第一个双下方法。

classA:

def__init__(self,a):

self.a=a

当调用A()实例化对象的时候,__init__方法会被自动调用,完成对象的初始化。

2. 运算符的双下方法

在类中定义运算符相关的双下方法,可以直接在类对象上做加减乘除、比较等操作。

这里,定义一个尺子类Rule,它包含一个属性r_len代表尺子的长度。

classRule:

def__init__(self,r_len):

self.r_len=r_len

2.1 比较运算符

如果想按照尺子的长度对不同的尺子做比较,需要在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参数,完成比较。

2.2 算术运算符

可以支持类对象加减乘除。

def__add__(self,other):

returnRule(self.r_len+other.r_len)

这里定义了__add__方法,对应的是+运算符,他会把两个尺子的长度相加,并生成新的尺子。

rule1=Rule(10)

rule2=Rule(5)

rule3=rule1+rule2

2.3 反向算术运算符

它支持其他类型的变量与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即可。

2.4 增量赋值运算符

增量赋值运算符是+=、-=、*=、/=等。

def__iadd__(self,other):

self.r_len+=other

returnself

rule1=Rule(10)

rule1+=5

除了__divmod__方法,其他的跟算数运算符一样,方面名前都加i。

2.4 位运算符

这部分支持按二进制进行取反、移位和与或非等运算。由于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

下面是位运算符的双下方法

这部分也支持反向位运算符和增量赋值位运算符,规则跟算数运算符一样,这里就不再赘述。

3.字符串表示

这部分涉及两个双下方法__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参数。

4.数值转换

调用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__优先级更高。

5.集合相关的双下方法

这部分可以像集合那样,定义对象长度、获取某个位置元素、切片等方法。

以__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__。

6.迭代相关的双下方法

可以在对象上使用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

7.类相关的双下方法

做 web 开发的朋友,用类相关的双下方法会更多一些。

7.1 实例的创建和销毁

实例的创建是__new__和__init__方法,实例的销毁是__del__方法。

__new__的调用早于__init__,它的作用是创建对象的实例(内存开辟一段空间),而后才将该实例传给__init__方法,完成实例的初始化。

由于__new__是类静态方法,因此它可以控制对象的创建,从而实现单例模式。

__del__方法在实例销毁时,被自动调用,可以用来做一些清理工作和资源释放的工作。

7.2 属性管理

类属性的访问和设置。包括__getattr__、__getattribute__、__setattr__和__delattr__方法。

__getattr__和__getattribute__的区别是,当访问类属性时,无论属性存不存在都会调用__getattribute__方法,只有当属性不存在时才会调用__getattr__方法。

7.3 属性描述符

控制属性的访问,一般用于把属性的取值控制在合理范围内。包括__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]之前,防止不合法的取值。

8.总结

虽然上面介绍的不是所有的双下方法,但也算是绝大多数了。

虽然双下方法里可以编写任意代码,但大家尽量编写与方法要求一样的代码。

关于“python双下方法有哪些,怎样应用的”的内容今天就到这,感谢各位的阅读,大家可以动手实际看看,对大家加深理解更有帮助哦。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章