Превращение функции python в класс без нарушения API

#python #oop

#python #ооп

Вопрос:

Итак, я создал библиотеку python для вычисления метрик ошибок между временными рядами (здесь ). Когда я впервые создавал библиотеку, я был начинающим программистом с практически нулевым предыдущим опытом, поэтому для каждой метрики ошибок я просто записывал ее как функцию. Сегодня я подумал, что было бы неплохо, если бы каждая метрика ошибок была представлена в виде класса, чтобы пользователь мог сделать что-то вроде следующего.

 # Name of the package
import HydroErr as he

he.r_squared.description  # Would return out a brief metric description
  

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

 import HydroErr as he
import numpy as np

he.r_squared(np.array([1, 2, 3]), np.array([1.1, 1.21, 1.3]))
# Out: 0.9966777408637874
  

Я не совсем уверен, как это сделать, и, что более важно, должен ли я это делать. Любая помощь будет оценена.

Ответ №1:

Чтобы превратить функцию в класс, вы можете использовать __call__ метод :

 def function(param):
    pass

# Becomes

class MyClass:
    def __call__(self, param):
        pass

    def other_method(self):
        pass

function = MyClass()
  

Оба могут использоваться следующим образом : function(42)

Ответ №2:

Вам не нужно превращать функции в классы, чтобы это работало:

 def r_squared(x, y):
    """ Do things... """
    return 56
r_squared.description = r_squared.__doc__
  

Вы можете написать декоратор, если таких функций много:

 def add_description(fn):
    fn.description = fn.__doc__

@add_description
def r_squared(x, y):
    """ Do things... """
    return 56
  

Комментарии:

1. Да, я прикрепил строку документа к .description , но вы можете поместить произвольные значения в атрибуты функции.

2. Так возможно ли это, потому что функции по существу представлены в виде объектов в python? Мне интересно, что функция может иметь такие свойства

3. Да, функции — это объекты, как и все остальное в Python (по крайней мере, все, с чем вы можете взаимодействовать напрямую). Не все объекты поддерживают назначение атрибутов, но функции поддерживают, что весьма полезно.