python - How to implement Integer+MyObject()?
问题描述
Asking just out of curiocity. I've been playing around with python, and noticed this behaviour:
(2).__add__(2)
results in 4, which is totally expected;(2).__add__('a')
results inNotImplemented
- nothing weird yet;'a'.__add__(2)
produces an exception.
But, when trying to create my own class like so:
class Integer:
def __init__(self, d):
self.val = d
def __add__(self, i):
return self.val+int(i)
def __iadd__(self, i):
self.val += int(i)
return self
def __int__(self):
return self.val
and comparing it to decimal.Decimal
, some weird stuff happens. They behave similarly in this case:
import decimal
a = Integer(2)
a += 2
print(int(a+2))
d = decimal.Decimal(2)
d += 2
print(int(d+2))
However, this is not as similar: 2+d
works normally while 2+a
throws an exception:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
2+a
TypeError: unsupported operand type(s) for +: 'int' and 'Integer'
even though (2).__add__(a)
and (2).__add__(d)
both produce NotImplemented
and a.__add__(2)
and d.__add__(2)
work normally.
What exactly is happening with decimal.Decimal
and how can I make this happen with my class?
解决方案
class Integer:
def __init__(self, d):
self.val = d
def __add__(self, i):
return self.val + int(i)
def __radd__(self, i):
return self.__add__(i) # might be different if operation is not commutative
def __iadd__(self, i):
self.val += int(i)
return self
def __int__(self):
return self.val
x = Integer(5) + 5
y = 5 + Integer(5)
推荐阅读
- swift - 基于另一个过滤器数组
- javascript - 阻止解析服务器写入日志文件
- c++ - c++ 在 pthread_join() 期间中止核心转储
- java - FileWriter 根本不写入文件但不抛出异常
- javascript - 允许为下载设置名称和目录的Javascript API?
- python - 如何从 csv 文件中获取过滤列表?
- powershell - 在 Powershell 中使用 foreach 循环返回 True/False 的函数
- jmeter - Jmeter 在不同机器上为相同版本的脚本给出不同的结果
- angularjs - AngularJS $http 没有将变量更新为 JSON 结果?
- ruby-on-rails - Rails 在导入 CSV 时插入带有 ID 的列