python重载运算符

class Rational(object):
    def __init__(self, p, q):
        self.p = p
        self.q = q
    def __add__(self, r):
        return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
    def __sub__(self, r):
        return Rational(self.p * r.q - self.q * r.p, self.q * r.q)
    def __mul__(self, r):
        return Rational(self.p * r.p, self.q * r.q)
    def __truediv__(self, r):
        return Rational(self.p * r.q, self.q * r.p)
    def __str__(self):
        return '%s/%s' % (self.p, self.q)
    __repr__ = __str__

r1 = Rational(1, 3)
print(r1)
r2 = Rational(7, 6)
r3 = r1 + r2
print(r2)
print(r3)

print(r1 - r2)
r3 = r1 / r2
print(r3)

要注意:

https://stackoverflow.com/questions/40770632/typeerror-unsupported-operand-types-for

Python3 uses special division names: __truediv__ and __floordiv__ for the / and //operators, respectively.

常见的运算符重载方法

在类中,对内置对象(例如,整数和列表)所能做的事,几乎都有相应的特殊名称的重载方法。下表列出其中一些最常用的重载方法。参见http://www.voidcn.com/article/p-xnoxxrbj-xd.html

方法 重载 调用
__init__ 构造函数 对象建立: X = Class(args)
__del__ 析构函数 X对象收回
__add__ 运算符+ 如果没有_iadd_,X+Y,X+=Y
__or__ 运算符|(位OR) 如果没有_ior_,X|Y, X|=Y
__repr__,__str__ 打印、转换 print(X)repr(X),str(X)
__call__ 函数调用 X(*args,**kargs)
__getattr__ 点号运算 X.undefined
__setattr__ 属性赋值语句 X.any = value
__delattr__ 属性删除 del X.any
__getattribute__ 属性获取 X.any
__getitem__ 索引运算 X[key],X[i:j],没__iter__时的for循环和其他迭代器
__setitem__ 索引赋值语句 X[key] = value,X[i:j] = sequence
__delitem__ 索引和分片删除 del X[key],del X[i:j]
__len__ 长度 len(X),如果没有__bool__,真值测试
__bool__ 布尔测试 bool(X),真测试
__lt__,__gt__, 特定的比较 X < Y,X > Y
__le__,__ge__, X<=Y,X >= Y  
__eq__,__ne__ X == Y,X != Y  
__radd__ 右侧加法 Other+X
__iadd__ 实地(增强的)加法 X += Y (or else __add__)
iter,next 迭代环境 I = iter(X),next(I)
__contains__ 成员关系测试 item in X (任何可迭代的)
__index__ 整数值 hex(X),bin(X),oct(X),O[X],O[X:]
__enter__,__exit__ 环境管理器 with obj as var:
__get__,__set__ 描述符属性 X.attr,X.attr = value,del X.attr
__new__ 创建 __init__之前创建对象

对于二元运算符, 有一个invoke的顺序表, 以__eq__为例

参见http://stackoverflow.com/questions/3588776/how-is-eq-handled-in-python-and-in-what-order 


总结起来就是 
左结合优先, 然后右结合, 然后其他

对于修改自己的二元操作, 比如 &=,先__iand__ 后__and__ 
在找不到__ixx__的情况下调用 __xx__

综合起来, 在尝试完了左边的运算符后, 才能尝试右边的运算符 

发布了374 篇原创文章 · 获赞 526 · 访问量 71万+

猜你喜欢

转载自blog.csdn.net/xun527/article/details/84578147
今日推荐