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__
综合起来, 在尝试完了左边的运算符后, 才能尝试右边的运算符