我正在为金融工具定价,每个金融工具对象都需要一个日计数器作为属性。有 4 种日计数器,它们的两种方法 year_fractionday_count 中的每一种都有不同的实现。金融工具的日计数器属性在定价时用于其他类,以了解如何适本地贴现曲线等。但是,所有日计数方法都是静态的,只是应用一些公式。

因此,尽管我在网上读到的所有内容都告诉我不要使用静态方法,而只使用模块级函数,但我看不到一种方法可以很好地传递正确的 DayCounter 而不实现类似的东西

class DayCounter:
    __metaclass__ = abc.ABCMeta

    @abc.abstractstaticmethod
    def year_fraction(start_date, end_date):
        raise NotImplementedError("DayCounter subclass must define a year_fraction method to be valid.")

    @abc.abstractstaticmethod
    def day_count(start_date, end_date):
        raise NotImplementedError("DayCounter subclass must define a day_count method to be valid.")


class Actual360(DayCounter):

    @staticmethod
    def day_count(start_date, end_date):
        # some unique formula

    @staticmethod
    def year_fraction(start_date, end_date):
        # some unique formula


class Actual365(DayCounter):

    @staticmethod
    def day_count(start_date, end_date):
        # some unique formula

    @staticmethod
    def year_fraction(start_date, end_date):
        # some unique formula


class Thirty360(DayCounter):

    @staticmethod
    def day_count(start_date, end_date):
        # some unique formula

    @staticmethod
    def year_fraction(start_date, end_date):
        # some unique formula

class ActualActual(DayCounter):

    @staticmethod
    def day_count(start_date, end_date):
        # some unique formula

    @staticmethod
    def year_fraction(start_date, end_date):
        # some unique formula

因此,在以工具作为参数传递的某些特定工具的定价引擎中,我可以根据需要使用工具的日计数器属性。

我是否遗漏了 Python 中更惯用/风格可接受的东西,或者这似乎适合用于静态方法类?

示例 :

我有一个 FxPricingEngine 类,它有一个 __init__ 方法传递了一个 FxInstrument 和随后的 underlying_instrument 属性。然后,为了使用我的定价引擎的 Value 方法,我需要使用特定日期计数器对曲线进行贴现。我有一个带有 YieldCurve 方法的 discount 类,我将 self.underlying_instrument.day_counter.year_fraction 传递给它,以便我可以应用正确的公式。实际上,这些类所做的就是为独特的实现提供一些逻辑组织。

最佳答案

事实上,面向对象在您的场景中没有任何意义:没有与您的类型的实例相关联的数据,因此某种类型的任何两个对象(例如 Thirty360 )将是相等的(即您只有单例) .

看起来您希望能够对行为的客户端代码进行参数化 - 您的方法操作的数据不是在构造函数中给出,而是通过方法的参数给出。在这种情况下,简单的自由函数可能是一个更直接的解决方案。

例如,给定一些在您的计数器上运行的虚构客户端代码,例如:

def f(counter):
  counter.day_count(a, b)
  # ...
  counter.year_fraction(x, y)

...你也可以想象一下,立即将两个函数作为参数而不是对象传递给它,例如有
def f(day_count, year_fraction):
    day_count(a, b)
    # ...
    year_fraction(x, y)

在调用方,您将传递普通函数,例如
f(thirty360_day_count, thirty360_year_fraction)

如果您愿意,您也可以为函数使用不同的名称,或者您可以在单独的模块中定义它们以获得命名空间。您还可以轻松传递像 way 这样的特殊函数(例如,如果您只需要 day_count 是正确的,但 year_fraction 可能是一个 noop)。

关于python - Python中的静态方法类和子类 - 有更好的设计模式吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36597318/

10-14 17:38
查看更多