4

金融商品の価格を設定していますが、各金融商品オブジェクトにはプロパティとしてデイ カウンターが必要です。2 つのメソッドのそれぞれに異なる実装を持つ 4 種類のデイ カウンターがありyear_fractionますday_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クラスがあります。実際、クラスが提供しているのは、独自の実装に論理的な編成を提供することだけです。discountself.underlying_instrument.day_counter.year_fraction

4

3 に答える 3

4

そのままでは、オブジェクト指向はシナリオでは意味がありません。型のインスタンスに関連付けられたデータがないため、何らかの型 (例: Thirty360) の 2 つのオブジェクトは等しくなります (つまり、シングルトンしかありません)。

クライアントコードの動作をパラメータ化できるようにしたいようです-メソッドが操作するデータはコンストラクタではなく、メソッドの引数を介して与えられます。その場合、単純な無料関数は、はるかに簡単な解決策になる可能性があります。

たとえば、次のようなカウンターで動作する架空のクライアント コードがあるとします。

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

...オブジェクトの代わりに、2 つの関数を引数としてすぐに渡すことを想像することもできます。

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 は不要な場合)。

于 2016-04-13T12:35:00.760 に答える
-1

いいえ

私が知っていることではありません。私の意見では、あなたのデザインパターンは問題ありません。特に、コードがクラスごとに 2 つ以上の関数に成長する可能性があり、クラス内の関数が接続されている場合。

関数の任意の組み合わせが可能な場合は、関数渡しアプローチを使用します。モジュールのアプローチとあなたのアプローチは非常に似ています。モジュールの長所または短所 (場合によって異なります) は、コードが多くのファイルに分割されることです。あなたのアプローチでは を使用できますisinstanceが、おそらくそれは必要ありません。

関数を直接渡す

関数が 1 つしかない場合は、クラスを使用する代わりに、この関数を直接渡すことができます。しかし、実装が異なる2 つ以上の関数があるとすぐに、クラスは問題ないように思えます。使い方を説明するためにdocstringを追加するだけです。1 つのクラスでの 2 つの関数の実装は、ある程度関連していると思います。

モジュールの使用

クラスの代わりにモジュール (モジュール Actual365DayCounter とモジュール Actual360DayCounter など) を使用して、if something: import Actual360DayCounter as daycounterとのようなものを使用できますelse: import Actual365ayCounter as daycounter

または、すべてのモジュールをインポートして辞書に入れることもできます (@freakish によるコメントのおかげで) のようMODULES = { 'Actual360': Actual360, ... }に、単に使用しますMODULES[my_var]

しかし、ソースコードを多くの小さなモジュールに分割することになるため、これがより良い設計パターンになるとは思えません。

別のオプション:

1 つの方法は、1 つのクラスのみを使用することです。

class DayCounter:
    def __init__(self, daysOfTheYear = 360):
        self.days_of_the_year = daysOfTheYear

を使って関数を作りますself.days_of_the_year。ただし、これdays_of_the_yearは実際に関数のパラメーターである場合にのみ機能します。if ... elif .. elif ...関数の実装で多くのを使用する必要がある場合、このアプローチはより悪いでしょう

于 2016-04-13T12:21:54.620 に答える
-1

率直に言って、静的メソッドをこのように定義してもあまり意味がありません。あなたのケースで静的メソッドが提供する唯一の目的は、関数名に名前空間を提供することです。Actual365.day_countつまり、 day_count が機能に属していることをより明確にするようにメソッドを呼び出すことができますActual365

しかし、 という名前のモジュールを定義することで、同じ考え方を実現できますactual365

import actual365
actual365.day_count()

オブジェクト指向に関する限り、あなたのコードは OOP 設計が提供する利点を提供していません。関数をクラスにラップしました。

すべてのメソッドが start_date と end_date を使用していることに気付きました。それらをインスタンス変数として使用するのはどうですか。

class Actual365(object):

    def __init__(self, start_date, end_date):
        self.start_date, self.end_date = start_date, end_date

    def day_count(self):
        # your unique formula

    ...

それに加えAbstractClassesて、Python のような Duck-Typed 言語ではあまり意味がありません。一部のオブジェクトが動作を提供している限り、一部の抽象クラスから継承する必要はありません。

それがうまくいかない場合は、関数だけを使用する方が良い方法かもしれません。

于 2016-04-13T11:58:59.827 に答える