网络编程
位置:首页>> 网络编程>> Python编程>> Python3 操作符重载方法示例

Python3 操作符重载方法示例

作者:LZ_Luzhuo  发布时间:2021-03-18 11:38:03 

标签:Python,操作符,重载

基础知识

实际上,“运算符重载”只是意味着在类方法中拦截内置的操作……当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果。以下是对重载的关键概念的复习:

  1. 运算符重载让类拦截常规的Python运算。

  2. 类可重载所有Python表达式运算符

  3. 类可以重载打印、函数调用、属性点号运算等内置运算

  4. 重载使类实例的行为像内置类型。

  5. 重载是通过特殊名称的类方法来实现的。

换句话说,当类中提供了某个特殊名称的方法,在该类的实例出现在它们相关的表达式时,Python自动调用它们。正如我们已经学习过的,运算符重载方法并非必须的,并且通常也不是默认的;如果你没有编写或继承一个运算符重载方法,只是意味着你的类不会支持相应的操作。然而,当使用的时候,这些方法允许类模拟内置对象的接口,因此表现得更一致。

以下代码以Python3.6.1为例

操作符重载方法: 类(class)通过使用特殊名称的方法(len(self))来实现被特殊语法(len())的调用


#coding=utf-8
# specialfuns.py 操作符重载方法
# 类(class)通过使用特殊名称的方法(__len__(self))来实现被特殊语法(len())的调用

# 构造 与 析构 方法
class demo1:

# 构造方法, 对象实例化时调用
 def __init__(self):
   print("构造方法")

# 析构方法, 对象被回收时调用
 def __del__(self):
   print("析构方法")

# new
class demo2(object):
 # __init__之前调用, 一般用于重写父类的__new__方法, 具体使用见 类 文章的 元类 代码部分(http://blog.csdn.net/rozol/article/details/69317339)
 def __new__(cls):
   print("new")
   return object.__new__(cls)

# 算术运算
class demo3:
 def __init__(self, num):
   self.data = num
 # +
 def __add__(self, other):
   return self.data + other.data
 # -
 def __sub__(self, other):
   return self.data - other.data
 # *
 def __mul__(self, other):
   return self.data * other.data
 # /
 def __truediv__(self, other):
   return self.data / other.data
 # //
 def __floordiv__(self, other):
   return self.data // other.data
 # %
 def __mod__(self, other):
   return self.data % other.data
 # divmod()
 def __divmod__(self, other):
   # 商(10/5),余数(10%5)
   return self.data / other.data, self.data % other.data
 # **
 def __pow__(self, other):
   return self.data ** other.data
 # <<
 def __lshift__(self, other):
   return self.data << other.data
 # >>
 def __rshift__(self, other):
   return self.data >> other.data
 # &
 def __and__(self, other):
   return self.data & other.data
 # ^
 def __xor__(self, other):
   return self.data ^ other.data
 # |
 def __or__(self, other):
   return self.data | other.data

class none:
 def __init__(self, num):
   self.data = num
# 反算术运算符(a+b, 若a不支持算术运算符,则寻找b的算术运算符)(注:位置变换, 在原始函数名前+r)
class demo4:
 def __init__(self, num):
   self.data = num
 # +
 def __radd__(self, other):
   return other.data + self.data
 # -
 def __rsub__(self, other):
   return other.data - self.data
 # *
 def __rmul__(self, other):
   return other.data * self.data
 # /
 def __rtruediv__(self, other):
   return other.data / self.data
 # //
 def __rfloordiv__(self, other):
   return other.data // self.data
 # %
 def __rmod__(self, other):
   return other.data % self.data
 # divmod()
 def __rdivmod__(self, other):
   return other.data / self.data, other.data % self.data
 # **
 def __rpow__(self, other):
   return other.data ** self.data
 # <<
 def __rlshift__(self, other):
   return other.data << self.data
 # >>
 def __rrshift__(self, other):
   return other.data >> self.data
 # &
 def __rand__(self, other):
   return other.data & self.data
 # ^
 def __rxor__(self, other):
   return other.data ^ self.data
 # |
 def __ror__(self, other):
   return other.data | self.data

# 增量赋值运算,(注:位置同原始函数,在原始函数名前+i)
class demo5():
 def __init__(self, num):
   self.data = num
 # +=
 def __iadd__(self, other):
   return self.data + other
 # -=
 def __isub__(self, other):
   return self.data - other
 # *=
 def __imul__(self, other):
   return self.data * other
 # /=
 def __itruediv__(self, other):
   return self.data / other
 # //=
 def __ifloordiv__(self, other):
   return self.data // other
 # %=
 def __imod__(self, other):
   return self.data % other
 # **=
 def __ipow__(self, other):
   return self.data ** other
 # <<=
 def __ilshift__(self, other):
   return self.data << other
 # >>=
 def __irshift__(self, other):
   return self.data >> other
 # &=
 def __iand__(self, other):
   return self.data & other
 # ^=
 def __ixor__(self, other):
   return self.data ^ other
 # |=
 def __ior__(self, other):
   return self.data | other

# 比较运算符
class demo6:
 def __init__(self, num):
   self.data = num
 # <
 def __lt__(self, other):
   return self.data < other.data
 # <=
 def __le__(self, other):
   return self.data <= other.data
 # ==
 def __eq__(self, other):
   return self.data == other.data
 # !=
 def __ne__(self, other):
   return self.data != other.data
 # >
 def __gt__(self, other):
   return self.data > other.data
 # >=
 def __ge__(self, other):
   return self.data >= other.data

# 一元操作符
class demo7:
 def __init__(self, num):
   self.data = num
 # + 正号
 def __pos__(self):
   return +abs(self.data)
 # - 负号
 def __neg__(self):
   return -abs(self.data)
 # abs() 绝对值
 def __abs__(self):
   return abs(self.data)
 # ~ 按位取反
 def __invert__(self):
   return ~self.data
 # complex() 字符转数字
 def __complex__(self):
   return 1+2j
 # int() 转为整数
 def __int__(self):
   return 123
 # float() 转为浮点数
 def __float__(self):
   return 1.23
 # round() 近似值
 def __round__(self):
   return 1.123

# 格式化
class demo8:
 # print() 打印
 def __str__(self):
   return "This is the demo."
 # repr() 对象字符串表示
 def __repr__(self):
   return "This is a demo."
 # bytes() 对象字节字符串表现形式
 def __bytes__(self):
   return b"This is one demo."
 # format() 格式化
 def __format__(self, format_spec):
   return self.__str__()

# 属性访问
class demo9:
 # 获取(不存在)属性
 def __getattr__(self):
   print ("访问的属性不存在")
 # getattr() hasattr() 获取属性
 def __getattribute__(self, attr):
   print ("访问的属性是%s"%attr)
   return attr
 # setattr() 设置属性
 def __setattr__(self, attr, value):
   print ("设置 %s 属性值为 %s"%(attr, value))
 # delattr() 删除属性
 def __delattr__(self, attr):
   print ("删除 %s 属性"%attr)

# ===================================================================
# 描述器(类(test1)的实例出现在属主类(runtest)中,这些方法才会调用)(注:函数调用,这些方法不会被调用)
class test1:
 def __init__(self, value = 1):
   self.value = value * 2
 def __set__(self, instance, value):
   print("set %s %s %s"%(self, instance, value))
   self.value = value * 2
 def __get__(self, instance, owner):
   print("get %s %s %s"%(self, instance, owner))
   return self.value
 def __delete__(self, instance):
   print("delete %s %s"%(self, instance))
   del self.value

class test2:
 def __init__(self, value = 1):
   self.value = value + 0.3
 def __set__(self, instance, value):
   print("set %s %s %s"%(self, instance, value))
   instance.t1 = value + 0.3
 def __get__(self, instance, owner):
   print("get %s %s %s"%(self, instance, owner))
   return instance.t1
 def __delete__(self, instance):
   print("delete %s %s"%(self, instance))
   del self.value

class runtest:
 t1 = test1()
 t2 = test2()

# ---

# 自定义property
class property_my:
 def __init__(self, fget=None, fset=None, fdel=None):
   self.fget = fget
   self.fset = fset
   self.fdel = fdel
 # 对象被获取(self自身, instance调用该对象的对象(demo9), owner调用该对象的对象类对象(demo9))
 def __get__(self, instance, owner):
   print("get %s %s %s"%(self, instance, owner))
   return self.fget(instance)
 # 对象被设置属性时
 def __set__(self, instance, value):
   print("set %s %s %s"%(self, instance, value))
   self.fset(instance, value)
 # 对象被删除时
 def __delete__(self, instance):
   print("delete %s %s"%(self, instance))
   self.fdel(instance)

class demo10:
 def __init__(self):
   self.num = None
 def setvalue(self, value):
   self.num = value
 def getvalue(self):
   return self.num
 def delete(self):
   del self.num
 x = property_my(getvalue, setvalue, delete)

# ===================================================================

# 自定义容器
class lis:
 def __init__(self, *args):
   self.lists = args
   self.size = len(args)
   self.startindex = 0
   self.endindex = self.size
 # len() 容器元素数量
 def __len__(self):
   return self.size;
 # lis[1] 获取元素
 def __getitem__(self, key = 0):
   return self.lists[key]
 # lis[1] = value 设置元素
 def __setitem__(self, key, value):
   pass
 # del lis[1] 删除元素
 def __delitem__(self, key):
   pass
 # 返回迭代器
 def __iter__(self):
   return self
 # rversed() 反向迭代器
 def __reversed__(self):
   while self.endindex > 0:
     self.endindex -= 1
     yield self[self.endindex]
 # next() 迭代器下个元素
 def __next__(self):
   if self.startindex >= self.size:
     raise StopIteration # 控制迭代器结束

elem = self.lists[self.startindex]
   self.startindex += 1
   return elem

# in / not in
 def __contains__(self, item):
   for i in self.lists:
     if i == item:
       return True
   return False

# yield 生成器(执行一次返回,下次继续执行后续代码返回)
def yielddemo():
 num = 0
 while 1: # 1 == True; 0 == False
   if num >= 10:
     raise StopIteration
   num += 1
   yield num

# 能接收数据的生成器
def yielddemo_1():
 while 1:
   num = yield
   print(num)

# with 自动上下文管理
class withdemo:
 def __init__(self, value):
   self.value = value
 # 返回值为 as 之后的值
 def __enter__(self):
   return self.value
 # 执行完成,退出时的数据清理动作
 def __exit__(self, exc_type, exc_value, traceback):
   del self.value

if __name__ == "__main__":
 # 构造与析构
 d1 = demo1()
 del d1

# new
 d2 = demo2()

# 算术运算符
 d3 = demo3(3)
 d3_1 = demo3(5)
 print(d3 + d3_1)
 print(d3 - d3_1)
 print(d3 * d3_1)
 print(d3 / d3_1)
 print(d3 // d3_1)
 print(d3 % d3_1)
 print(divmod(d3, d3_1))
 print(d3 ** d3_1)
 print(d3 << d3_1)
 print(d3 >> d3_1)
 print(d3 & d3_1)
 print(d3 ^ d3_1)
 print(d3 | d3_1)

# 反运算符
 d4 = none(3)
 d4_1 = demo4(5)
 print(d4 + d4_1)
 print(d4 - d4_1)
 print(d4 * d4_1)
 print(d4 / d4_1)
 print(d4 // d4_1)
 print(d4 % d4_1)
 print(divmod(d4, d4_1))
 print(d4 ** d4_1)
 print(d4 << d4_1)
 print(d4 >> d4_1)
 print(d4 & d4_1)
 print(d4 ^ d4_1)
 print(d4 | d4_1)

# 增量赋值运算(测试时注释其他代码)
 d5 = demo5(3)
 d5 <<= 5
 d5 >>= 5
 d5 &= 5
 d5 ^= 5
 d5 |= 5
 d5 += 5
 d5 -= 5
 d5 *= 5
 d5 /= 5
 d5 //= 5
 d5 %= 5
 d5 **= 5
 print(d5)

# 比较运算符
 d6 = demo6(3)
 d6_1 = demo6(5)
 print(d6 < d6_1)
 print(d6 <= d6_1)
 print(d6 == d6_1)
 print(d6 != d6_1)
 print(d6 > d6_1)
 print(d6 >= d6_1)

# 一元操作符(测试时注释其他代码)
 d7 = demo7(-5)
 num = +d7
 num = -d7
 num = abs(d7)
 num = ~d7
 print(num)
 print(complex(d7))
 print(int(d7))
 print(float(d7))
 print(round(d7))

# 格式化
 d8 = demo8()
 print(d8)
 print(repr(d8))
 print(bytes(d8))
 print(format(d8, ""))

# 属性访问
 d9 = demo9()
 setattr(d9, "a", 1) # => 设置 a 属性值为 1
 print(getattr(d9, "a")) # => a / 访问的属性是a
 print(hasattr(d9, "a")) # => True / 访问的属性是a
 delattr(d9, "a") # 删除 a 属性
 # ---
 d9.x = 100 # => 设置 x 属性值为 100
 print(d9.x) # => x / 访问的属性是x
 del d9.x # => 删除 x 属性

# 描述器
 r = runtest()
 r.t1 = 100 # => <__main__.test1> <__main__.runtest> 100
 print(r.t1) # => 200 / <__main__.test1> <__main__.runtest> <class '__main__.runtest'>
 del r.t1 # => <__main__.test1> <__main__.runtest>
 r.t2 = 200 # => <__main__.test2> <__main__.runtest> 200 / <__main__.test1> <__main__.runtest> 200.3
 print(r.t2) # => 400.6 / <__main__.test2> <__main__.runtest> <class '__main__.runtest'> / <__main__.test1> <__main__.runtest> <class '__main__.runtest'>
 del r.t2 # <__main__.test2> <__main__.runtest>
 # ---
 # 自定义property
 d10 = demo10()
 d10.x = 100; # => <__main__.property_my> <__main__.demo10> 100
 print(d10.x) # => 100 / <__main__.property_my> <__main__.demo10> <class '__main__.demo10'>
 del d10.x # => <__main__.property_my> <__main__.demo10>
 d10.num = 200;
 print(d10.num) # => 200
 del d10.num

# 自定义容器(迭代器Iterator)
 lis = lis(1,2,3,4,5,6)
 print(len(lis))
 print(lis[1])
 print(next(lis))
 print(next(lis))
 print(next(lis))
 for i in lis:
   print (i)
 for i in reversed(lis):
   print (i)
 print(3 in lis)
 print(7 in lis)
 print(3 not in lis)
 print(7 not in lis)

# yield 生成器(可迭代对象Iterable)
 for i in yielddemo():
   print (i)
 # ---
 iters = iter(yielddemo())
 print(next(iters))
 print(next(iters))

# --- 发送数据给生成器 ---
 iters = yielddemo_1()
 next(iters)
 iters.send(6) # 发送数据并执行
 iters.send(10)

# with 自动上下文管理
 with withdemo("Less is more!") as s:
   print(s)

来源:http://blog.csdn.net/rozol/article/details/70769628

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com