python中__truediv__的运算符重载
Posted
技术标签:
【中文标题】python中__truediv__的运算符重载【英文标题】:operator overloading for __truediv__ in python 【发布时间】:2015-05-23 05:32:16 【问题描述】:我正在尝试在 python 中重载除法运算符。
class Fraction:
def __init__(self,top,bottom):
def gcd(m, n):
while m % n != 0:
old_m = m
old_n = n
m = old_n
n = old_m % old_n
return n
common = gcd(top,bottom)
self.num = top/common
self.den = bottom/common
def __str__ (self):
return str(self.num) + "/" + str(self.den)
def get_num(self):
return self.num
def get_den(self):
return self.den
def __add__(self, other_fraction):
new_num = self.num * other_fraction.den + self.den * other_fraction.num
new_den = self.den * other_fraction.den
return Fraction(new_num, new_den)
def __sub__(self, other_fraction):
new_num = self.num * other_fraction.den - self.den * other_fraction.num
new_den = self.den * other_fraction.den
return Fraction(new_num, new_den)
def __mul__ (self, other_fraction):
new_num = self.num * other_fraction.num
new_den = self.den * other_fraction.den
return Fraction(new_num, new_den)
def __truediv__(self, other_fraction):
new_num = self.num * other_fraction.den
new_den = self.den * other_fraction.num
return Fraction(new_num, new_den)
def __eq__(self, other):
first_num = self.num * other.den
second_num = other.num * self.den
return first_num == second_num
a = Fraction(10,20)
b = Fraction(30,20)
print a
print "numerator is",a.get_num()
print "denominator is",a.get_den()
print "equality is",(a==b)
print "sum is",(a+b)
print "difference is",(a-b)
print "product is",(a*b)
print "division is",(a/b)
但我在__truediv__
收到错误:
TypeError: /: 'instance' 和不支持的操作数类型 '实例'
代码有什么问题?
【问题讨论】:
from fraction import Fraction
【参考方案1】:
来自docs:
object.__div__(self, other) object.__truediv__(self, other)
除法运算符 (/) 由这些方法实现。这 当
__future__.division
生效时使用__truediv__()
方法,否则使用__div__()
。如果这两种方法中只有一种是 已定义,该对象将不支持备用中的除法 语境;将改为引发 TypeError。
还有here:
Future 语句是对编译器的一个指令,即特定的 [python 程序] 应该使用将被编译的语法或语义 在 Python 的未来版本中可用。未来 声明旨在简化向 Python 未来版本的迁移 对语言进行不兼容的更改。它允许使用 发布前的新功能 功能成为标准。
future_statement: from __future__ import feature
Python 2.x 识别的特征是 unicode_literals, print_function、absolute_import、除法、生成器、nested_scopes 和 with_statement
现在,进行一些测试:
~$ python2.7
Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 3/2
1
>>> exit()
~$ python3.2
Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 3/2
1.5
所以,你看,/
运算符的效果在 python 3.x 中发生了变化。您也可以在下面的示例中看到这一点:
class Dog(object):
def __div__(self, other):
print("__div__ called")
def __truediv__(self, other):
print("__truediv__ called")
Dog() / Dog()
--output:--
~/python_programs$ python2.7 myprog.py
__div__ called
~/python_programs$ python3.4 myprog.py
__truediv__ called
因为__truediv__
在python 2.x中没有被/
操作符调用,所以在python 2.x中覆盖__truediv__
没有效果。
PEP 238 - PEP 238 -- Changing the Division Operator
We propose the following transitional measures:
- Classic division will remain the default in the Python 2.x
series; true division will be standard in Python 3.0.
- The // operator will be available to request floor[, i.e. integer,]
division unambiguously.
- The future division statement, spelled "from __future__ import
division", will change the / operator to mean true division
throughout the [program]
现在,看看这里发生了什么:
from __future__ import division
class Dog(object):
def __div__(self, other):
print("__div__ called")
def __truediv__(self, other):
print("__truediv__ called")
Dog() / Dog()
--output:--
~/python_programs$ python2.7 myprog.py
__truediv__ called
~/python_programs$ python3.4 myprog.py
__truediv__ called
现在,您可以在 python 2.x 中获得 /
运算符的 python3.x 效果。因此,现在您可以覆盖 __truediv__
以使 /
运算符执行您想要的操作。
注意,如果你想在 python 3.x 中进行整数除法,即3/2 => 1
,那么你必须使用//
运算符,它由__floordiv__
实现。同样,如果您在 python 2.x 中执行 from __future__ import division
,那么要获得整数除法,您必须使用 //
运算符;如果你想在一个类中重写//
操作符,你需要实现__floordiv__
。
【讨论】:
非常感谢您的详细解答【参考方案2】:object.__truediv__()
特殊方法仅与/
运算符一起使用,并且仅当您已将 Python 编译器切换为使用真正的除法时:
from __future__ import division
如果您没有使用该导入,/
运算符将调用 object.__div__()
special method(如果存在)。
另一方面,//
运算符调用 object.__floordiv__()
special method,您没有实现。
【讨论】:
以上是关于python中__truediv__的运算符重载的主要内容,如果未能解决你的问题,请参考以下文章