python 重载

python 重载,第1张

重载是面向对象的一个重要概念,在很多程序实现中都会用到。最常见的是运算重载,比如+、-、x、÷等。python可以重载的方法一共有118个,有些是常用的,有些是不常用的。本文总结了所有的重载方法并提供实现实例以及说明供大家参考。为了便于阅读,本文分为常用的重载方法、其余重载方法以及重载方法列表。

一、重载的概念

重载的概念及时重新编写python类中的方法,以实现特定的算法或者处理。比如自定义的类的相加。

二、常用的重载方法 1. 运算符号

python支持运算符如下:

运算类型对象在左侧对象在右侧复合赋值
加法__add____radd____iadd__
减法__sub____rsub____isub__
乘法__mul____rmul____imul__
除法__truediv____rdiv____idiv__
求余__mod____rmod____imod_
运算符+
代码如下:

```python
class op(object):
    def __init__(self,x=0,y=0):
        self.x = x
        self.y = y

    def __str__(self): #重载__str__
        return ("x={} y={}".format(self.x,self.y))

    def __add__(self,other):
        print("对象在左侧")
        return op(self.x+other.x,self.y+other.y)

    def __radd__(self,other):
        print("对象在右侧")
        return op(self.x + other[0], self.y + other[1])

    def __iadd__(self, other):
        print("+=运算")
        self.x += other.x
        self.y += other.y
        return self

a = op(10,2)
c = a + op(5,9)
print("左侧:",c) #10+5,2+9
c = [1,2]+a
print("右侧",c) #1+10,2+2
c += a 
print("+=",c) #11+10,4+2

结果如下:

对象在左侧
左侧: x=15 y=11
对象在右侧
右侧 x=11 y=4
+=运算
+= x=21 y=6

不仅可以编写里2个对象的相加,也可以通过重载编写对象与数组,数字等方式的相加。不过这一点python不如C++方便。比如上面的例子中定义了对象+对象,就不能定义对象+数组。在右侧相加的方法中,定义了数组+对象。二者之间是有区别的。
其他的-、x、÷运算可以参考运算符+。
此外还有其他的运算,比如divmod(a//b,a%b)。
下面的示例是divmod

import math

class v(object):
    def __init__(self,x=0.,y=0.):
        self.x = x
        self.y = y

        self.xmod = None
        self.ymod = None
    def __divmod__(self, other):
        return divmod(self.x,other.x),divmod(self.y,other.y)

x,y = divmod(v(100,200),v(20,30))
print(x,y)

结果:

(5, 0) (6, 20)
2. 位运算

python对象的位运算有:&、|、^、~、>>、<<,含义如下:

位运算含义示例方法
&按位与4&2=0__and__
|按位或4&2=6__or__
^按位异或3^2=1__xor__
~按位取反~2=-3__invert__
>>右移8>>1=4__rshift__
<<左移8<<1=16__lshift__

位运算符也有赋值位运算,|=、&=、^=、>>=、<<=

#coding:utf8

class v(object):
    def __init__(self,x=0,y=0):
        self.x = x
        self.y = y

    def __or__(self, other):
        return v(self.x|other.x,self.y|other.y)

    def __and__(self,other):
        return v(self.x&other.x,self.y&other.y)

    def __ior__(self, other):
        print("ior",end=" ")
        self.x |= other.x
        self.y |= other.y
        return self

    def __iand__(self, other):
        print("iand",end=" ")
        self.x &= other.x
        self.y &= other.y
        return self

    def __xor__(self, other):
        return v(self.x^other.x,self.y^other.y)

    def __ixor__(self, other):
        print("ixor",end=" ")
        self.x ^= other.x
        self.y ^= other.y
        return self

    def __invert__(self):
        self.x = ~self.x
        self.y = ~self.y
        return self

    def __lshift__(self, other):
        return v(self.x<<other.x,self.y<<other.y)

    def __ilshift__(self, other):
        print("ilshift",end=" ")
        self.x = self.x << other.x
        self.y = self.y << other.y
        return self

    def __rshift__(self, other):
        return v(self.x>>other.x,self.y>>other.y)

    def __irshift__(self, other):
        print("irshift",end=" ")
        self.x = self.x >> other.x
        self.y = self.y >> other.y
        return self

    def __str__(self):
        return "x={},y={}".format(self.x,self.y)

a=v(3,6)
b=v(2,8)
c=v(3,6)
print("(",a,") | (",b,")=",a|b)
print("(",a,") & (",b,")=",a&b)
print("(",a,") ^ (",b,")=",a^b)
print("(",a,") >> (",b,")=",a>>b)
print("(",a,") << (",b,")=",a<<b)
print("~(",c,") =",~a) #~a 会改变a的值,用c暂存
a=v(3,6)
a ^= b
print(a)
a=v(3,6)
a &= b
print(a)
a=v(3,6)
a|=b
print(a)
a=v(3,6)
a>>=b
print(a)
a=v(3,6)
a<<=b
print(a) 

结果:

( x=3,y=6 ) | ( x=2,y=8 )= x=3,y=14
( x=3,y=6 ) & ( x=2,y=8 )= x=2,y=0
( x=3,y=6 ) ^ ( x=2,y=8 )= x=1,y=14
( x=3,y=6 ) >> ( x=2,y=8 )= x=0,y=0
( x=3,y=6 ) << ( x=2,y=8 )= x=12,y=1536
~( x=3,y=6 ) = x=-4,y=-7
ixor x=1,y=14
iand x=2,y=0
ior x=3,y=14
irshift x=0,y=0
ilshift x=12,y=1536

同样的有rand、ror、rshift、rlshift、rrshift等右侧位运算符。跟第一节的定义一样的,可以参考。

3.重要方法

比较常用的重要方法有:__init__。

__init__ 构造函数

用来初始化类。与C++不同的是python只能有一个初始化构造函数。可以写多个,但是只有最后一个有效。
如果需要多个不同的构造函数,可以把所有的成员变量作为构造函数的初始化参数,并且设置初始值。在创建对象的时候,通过参数=数值的形式实现不同的构造函数。示例如下:

#coding:utf8

class v(object):
    def __init__(self,x=0,y=None):
        self.x = x
        self.y = y

    def __str__(self):
        if self.y:
            return "x={0},y={1}".format(self.x,self.y)
        else:
            return "x={0},y={1}".format(self.x, "None")

a = v(x=1) #只有成员x
b = v(y=[10,11,12]) #只有成员y
c = v(x=100,y=[1,2,3]) #x和y都有
n = v() #使用默认值

print(a,b,c,n)

结果如下:

x=1,y=None
x=0,y=[10, 11, 12]
x=100,y=[1, 2, 3]
x=0,y=None
__str__和__repr__

见上例。二者实现的功能类似。如果是打印对象数组,系统调用的是__repr__

4.关系运算

关系运算是比较2个对象,包括:

关系运算含义
__lt__X
__gt__X>Y
__le__X<=Y
__ge__X>=Y
__eq__X==Y
__ne__X!=Y
__cmp__比较X和Y,用于sorted,返回值是-1,1,0

示例如下:

class v(object):
    def __init__(self,x=0):
        self.x = x

    def __lt__(self,other):
        return self.x < other.x

    def __gt__(self, other):
        return self.x > other.x

    def __le__(self, other):
        return self.x <= other.x

    def __ge__(self, other):
        return self.x >= other.x

    def __ne__(self, other):
        return self.x != other.x

    def __eq__(self, other):
        return self.x == other.x


print(v(1)<v(2))
print(v(1)>v(2))
print(v(2)<=v(2))
print(v(3)>=v(2))
print(v(1)!=v(2))
print(v(3)==v(3))

结果:

True
False
True
True
True
True
5. 转换

转为int,float等。具体转换功能如下:

转换类型方法
bool__bool__
bytes__bytes__
complex__complex__
float__float__
int__int__

示例如下:

#coding:utf8

class v(object):
    def __init__(self,x=0,y=0):
        self.x = x
        self.y = y

    def __int__(self):
        return int(self.x)

    def __float__(self):
        return float(self.x)

    def __bool__(self):
        return bool(self.x)

    def __bytes__(self):
        return bytes(self.x)

    def __complex__(self):
        return complex(self.x)

    def __str__(self):
        return "x={},y={}".format(self.x,self.y)

a=v(3,6)
print("int:",int(a))
print("float:",float(a))
print("bool:",bool(a))
print("bytes:",bytes(a))
print("complex:",complex(a))

结果:

int: 3
float: 3.0
bool: True
bytes: b'\x00\x00\x00'
complex: (3+0j)

需要注意的是返回的一定是数字类型,不能是对象。

6. 数学运算

数学运算包括round、ceil、floor等。具体如下:

数学运算方法说明
abs__abs__绝对值
ceil__ceil__向上取整
floor__floor__向下取整
pow__pow__幂次运算
round__round__截取
trunc__trunc__截断为整数
matmul__matmul__矩阵乘积。与numpy的功能一致
pos__pos__返回数值本身
neg__neg__返回相反数

示例如下:

#coding:utf8
import math

class v(object):
    def __init__(self,x=0.,y=0.):
        self.x = x
        self.y = y
    def __abs__(self):
        return v(abs(self.x),abs(self.y))

    def __ceil__(self):
        return v(math.ceil(self.x),math.ceil(self.y))

    def __floor__(self):
        return v(math.floor(self.x),math.floor(self.y))

    def __pow__(self, power, modulo=None):
        return v(pow(self.x,power,modulo), pow(self.y,power,modulo))

    def __round__(self,n=None):
        return v(round(self.x,n),round(self.y,n))

    def __trunc__(self):
        return v(math.trunc(self.x),math.trunc(self.y))

    def __str__(self):
        return "x={},y={}".format(self.x,self.y)

a=v(3.14,6.28)
print(abs(v(-1,2)))
print(math.ceil(a))
print(math.floor(a))
print(pow(a,2))
print(round(a,1))
print(math.trunc(a))

结果:

x=1,y=2
x=4,y=7
x=3,y=6
x=9.8596,y=39.4384
x=3.1,y=6.3
x=3,y=6
7. 遍历与查找

遍历是遍历类中的数组、字典等成员。方法如下:

方法说明使用
__getitem__获取元素x[key]
__setitem__设置指定位置元素x[key]=value
__delitem__删除指定位置元素del x[key]
__missing__判断是否存在索引key由__getitem__被动调用
__contains__判断item是否在成员中x.__contains__(item)
#coding:utf8

class v(object):
    def __init__(self,x=None):
        self.x = x

    def __getitem__(self, item):
        return self.x[item]

    def __setitem__(self, key, value):
        self.x[key]=value
    def __delitem__(self, key):
        self.x.pop(key)

    def __str__(self):
        return "x={}".format(self.x)
a=v([1,2,3,10])
print(a[3])
a[3]=100
print(a[3])
del a[2]
print(a)

结果:

10
100
x=[1, 2, 100]
8. 属性

属性包括len、sizeof等。具体如下:

方法说明使用
__len__对象大小len(x)
__sizeof__返回对象所占的内存字节大小x.__sizeof__()
9. 其他算法
方法说明使用
__hash__返回hash值 hash(x)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/756224.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存