Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Square Root for Class Instances

I am currently implementing a class that can handle numeric data associated with physical units.

I would like to implement a way of calculating the square root of an instance. Assume that you have an instance of a class that has attributes value and name:

from math import sqrt

class Foo:
   def __init__(self, value, name)
      self.value = value
      self.name = name

   def __sqrt__(self):
      return sqrt(self.value)

I would like to implement a function similar to the magic methods like add(self, other) that would calculate the squareroot when I call the math.sqrt() function:

A = Foo(4, "meter")
root = math.sqrt(A)

should return call the A.sqrt() function.

like image 506
Torilla Avatar asked Dec 06 '18 15:12

Torilla


People also ask

How do you use square root in Python programming?

sqrt() function is an inbuilt function in Python programming language that returns the square root of any number. Syntax: math.sqrt(x) Parameter: x is any number such that x>=0 Returns: It returns the square root of the number passed in the parameter.

How do you find the square root of a complex number in Python?

The cmath. sqrt() method returns the square root of a complex number.

Is there any square root function in Python?

The math. sqrt() method returns the square root of a number. Note: The number must be greater than or equal to 0.

How do you find the square root of a list in Python?

Python has a predefined sqrt() function that returns the square root of a number. It defines the square root of a value that multiplies itself to give a number. The sqrt() function is not used directly to find the square root of a given number, so we need to use a math module to call the sqrt() function in Python.


2 Answers

You can't without reassigning math.sqrt to a custom function. If you want to allow Foo to be cast to int or float you can implement __int__ and __float__ and cast before calling math.sqrt:

class Foo:
    def __init__(self, value, name)
        self.value = value
        self.name = name

    def __float__(self):
        return float(self.value)

    def __int__(self):
        return int(self.value)

A = Foo(4, "meter")
root = math.sqrt(float(A))

EDIT: According to the comments below, it seems that you can invoke math.sqrt(A) directly if Foo implements __float__ due to how the math module is implemented. I would still rather be explicit than implicit.

like image 119
MEE Avatar answered Nov 02 '22 23:11

MEE


There's no trivial/out-of-the-box way to wire math.sqrt to call Foo.__sqrt__.

Just implement sqrt in Foo:

class Foo:
     ...
     def sqrt(self):
          return sqrt(self.value)

A = Foo(4, "meter")
root = A.sqrt()

If for some reason you insist, it can be hacked, but I don't see any reason why you would want to do that:

from math import sqrt

class Foo:
    def __init__(self, value, name):
        self.value = value
        self.name = name

    def __sqrt__(self):
        return sqrt(self.value)

orig_sqrt = sqrt

def my_sqrt(value):
    if isinstance(value, Foo):
        return orig_sqrt(value.value)
        # or return value.__sqrt__()
    else:
        return orig_sqrt(value)

sqrt = my_sqrt

A = Foo(4, "meter")
print(sqrt(A))
# 2.0
print(sqrt(4))
# 2.0
like image 44
DeepSpace Avatar answered Nov 02 '22 22:11

DeepSpace