类实例的Python平方根

时间:2018-12-06 15:00:25

标签: python magic-methods

我目前正在实现一个可以处理与物理单位相关的数字数据的类。

我想实现一种计算实例平方根的方法。假设您有一个具有属性value和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)

我想实现类似于 add (自身,其他)这样的魔术方法的功能,当我调用math.sqrt()函数时,该方法将计算平方根:

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

应返回调用A. sqrt ()函数。

3 个答案:

答案 0 :(得分:3)

您不能不将math.sqrt重新分配给自定义功能。如果要允许将Foo强制转换为intfloat,则可以实现__int____float__并强制转换,然后调用math.sqrt:< / p>

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))

编辑:根据下面的评论,由于数学模块的实现方式,如果math.sqrt(A)实现Foo,似乎可以直接调用__float__。我仍然宁愿明确而不是隐含。

答案 1 :(得分:2)

没有简单/开箱即用的方式连接math.sqrt来呼叫Foo.__sqrt__

只需在sqrt中实现Foo

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

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

如果出于某种原因您坚持认为它可以被黑客入侵,但我看不出您为什么要这样做:

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

答案 2 :(得分:0)

sqrt没有像其他数字函数那样神奇的方法。

您可以在类中定义一个sqrt方法,如另一个答案所指出。

您还可以做的是创建自己的sqrt函数,如果传递了该类的实例,则会对该类的属性调用math.sqrt

import math

def sqrt(x):
    if isinstance(x, Foo):
        return math.sqrt(x.value)
    return math.sqrt(x)

但是,这是很棘手的,除非您出于某种原因绝对需要在混合类型的容器上不加选择地调用sqrt,否则不建议这样做。