Python Class 个实例的平方根

Python Square Root for Class Instances

我目前正在实施 class 可以处理与物理单位关联的数字数据。

我想实现一种计算实例平方根的方法。假设您有一个 class 的实例,它具有属性值和名称:

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(self, other) 等魔术方法的函数,它会在我调用 math.sqrt() 时计算平方根功能:

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

应该return调用 A.sqrt() 函数。

没有 trivial/out-of-the-box 方式连接 math.sqrt 来调用 Foo.__sqrt__

只需在 Foo 中实施 sqrt:

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

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

您可以在 class 中定义一个 sqrt 方法,正如另一个答案中所指出的那样。

您还可以创建自己的 sqrt 函数,如果传递 class 的实例,该函数会调用 math.sqrt 的 class 属性。

import math

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

然而,这相当 hacky 并且不推荐它,除非你出于某种原因绝对需要在混合类型的容器上不加区别地调用 sqrt

您不能不将 math.sqrt 重新分配给自定义函数。如果你想允许 Foo 被转换为 intfloat 你可以实现 __int____float__ 并在调用 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))

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