Summary
How can I overload the built-in float for my class so when I call float() on an instance of it, my custom function gets called instead of the default built-in?
My Class
Hi, I was coding my own Fractions class (for arbitrarily-high floating-point operation precision). It goes like this (I haven't yet finished it):
class Fractions:
"""My custom Fractions class giving arbitarilly high precision w/ floating-point arithmetic."""
def __init__(self, num = 0, denom = 1):
"""Fractions(num = 0, denom = 1) -> Fractions object
Class implementing rational numbers. In the two-argument form of the constructor, Fraction(8, 6) will produce a rational number equivalent to 4/3.
Both arguments must be rational, i.e, ints, floats etc. .The numerator defaults to 0 and the denominator defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
Fractions can also be constructed from:
- numeric strings that are valid float constructors (for example, '-2.3' or '1e10')
- strings of the form '123/456'"""
if '/' in str(num):
self.num, self.denom = map(float, num.split('/')) #'x/y'
else:
self.num, self.denom = float(num), float(denom) #(num, denom)
self.normalize()
def __repr__(self):
print self.num + '/' + self.denom
def __invert__(self):
self.num, self.denom = self.denom, self.num
def normalize(self):
num, denom = self.num, self.denom
#Converting `num` and `denom` to ints if they're not already
if not float(num).is_integer():
decimals = len(str(float(num) - int(num))) - 1
num, denom = num*decimals, denom*decimals
if float(denom).is_integer():
decimals = len(str(float(denom) - int(denom))) - 1
num, denom = num*decimals, denom*decimals
#Negatives
if denom < 0:
if num < 0:
num, denom = +num, +denom
else:
num, denom *= -1
#Reducing to the simplest form
from MyModules import GCD
GCD_ = GCD(num, denom)
if GCD_:
self.num, self.denom /= GCD_
#Assigning `num` and `denom`
self.num, self.denom = num, denom
The Question
Now, I want to implement a method that overloads float(), i.e., it is called when an instance of my class is passed to float(). How do I do that? At first I thought:
def float(self):
return self.num/self.denom
But that didn't work. Neither did a Google Search or the Python Docs help. Is it even possible to implement it?
解决方案
Define the __float__() special method on your class.
class MyClass(object):
def __float__(self):
return 0.0
float(MyClass()) # 0.0
Note that this method must return a float! The calculation self.num / self.denom, returns an int by default in versions of Python prior to 3.0 assuming both operands are integers. In this case you'd just make sure one of the operands is a float: float(self.num) / self.denom for example.