Корень Python для экземпляров классов - PullRequest
0 голосов
/ 06 декабря 2018

В настоящее время я реализую класс, который может обрабатывать числовые данные, связанные с физическими единицами.

Я хотел бы реализовать способ вычисления квадратного корня экземпляра.Предположим, что у вас есть экземпляр класса, который имеет атрибуты 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 (self, other)это вычислит квадратный корень, когда я вызову функцию math.sqrt ():

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

должен вернуть вызов функции A. sqrt ().

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Для sqrt нет магического метода, как для других числовых функций.

Вы можете определить метод sqrt в своем классе, как указано в другом ответе.

То, что вы могли бы также сделать, это сделать свою собственную sqrt функцию, которая вызывает math.sqrt для атрибута вашего класса, если передан экземпляр этого класса.

import math

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

Это, однако, довольно хакерскийЯ не рекомендую это делать, если вам по какой-то причине не нужно без разбора вызывать sqrt для контейнера смешанных типов.

0 голосов
/ 06 декабря 2018

Вы не можете без переназначения 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))

РЕДАКТИРОВАТЬ: Согласнокомментарии ниже, кажется, что вы можете вызвать math.sqrt(A) напрямую, если Foo реализует __float__ из-за того, как реализован математический модуль.Я все равно предпочел бы быть явным, чем неявным.

0 голосов
/ 06 декабря 2018

Нет простого / нестандартного способа соединения 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
...