sud*_* ks 6 python overloading operator-keyword python-2.7
我试图在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)
Run Code Online (Sandbox Code Playgroud)
但这__truediv__是错误的
TypeError:/:'instance'和'instance'的不支持的操作数类型
请帮忙解释代码有什么问题?
Mar*_*ers 12
该object.__truediv__()特殊方法仅用于与/运营商,那么只有当你切换的Python编译器使用真司:
from __future__ import division
Run Code Online (Sandbox Code Playgroud)
如果您没有使用该导入,则/运算符会调用object.__div__()特殊方法(如果存在).
//另一方面,运算符调用您未实现的object.__floordiv__()特殊方法.
7st*_*tud 11
来自文档:
Run Code Online (Sandbox Code Playgroud)object.__div__(self, other) object.__truediv__(self, other)除法运算符(/)由这些方法实现.该
__truediv__()方法__future__.division在有效时使用,否则__div__()使用.如果只定义了这两种方法中的一种,则该对象将不支持备用上下文中的除法; 将引发TypeError.
而在这里:
未来的声明是编译器的一个指令,即应该使用将来在Python的未来版本中提供的语法或语义来编译特定的[python程序].未来的声明旨在简化向未来版本的Python的迁移,从而引入对语言的不兼容更改.它允许在发布之前使用新功能,其中功能成为标准.
Run Code Online (Sandbox Code Playgroud)future_statement: from __future__ import featurePython 2.x识别的功能是unicode_literals,print_function,absolute_import,division,generators,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
Run Code Online (Sandbox Code Playgroud)
所以,你看,/运算符的效果在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
Run Code Online (Sandbox Code Playgroud)
因为python 2.x中__truediv__的/操作符没有调用,所以在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]
Run Code Online (Sandbox Code Playgroud)
现在,看看这里发生了什么:
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
Run Code Online (Sandbox Code Playgroud)
现在,您将/在python 2.x中获得运算符的python3.x效果.所以,现在你可以覆盖__truediv__以使/操作员做你想做的事.
注意,如果你想在python 3.x中进行整数除法3/2 => 1,那么你必须使用由//它实现的运算符__floordiv__.同样,如果你from __future__ import division在python 2.x中进行,那么要获得整数除法,你必须使用//运算符; 如果要覆盖//类中的运算符,则需要实现__floordiv__.