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
被转换为 int
或 float
你可以实现 __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)
。我还是宁愿明示也不愿含蓄。
我目前正在实施 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
被转换为 int
或 float
你可以实现 __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)
。我还是宁愿明示也不愿含蓄。