How to overload `float()` for a custom class in Python?

泄露秘密 提交于 2019-12-23 07:39:27

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/10034097/how-to-overload-float-for-a-custom-class-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!