2016-10-04 12 views
1

私はABCをPythonで使用して、特定のインターフェイスへのコーディングを強制しました。しかし、メソッドが実装されていないクラスを作成し、実際の実装で継承してオーバーライドするだけで、基本的に同じことができるようです。 ABCがなぜ追加されたのか、なぜこのコーディングパターンを言語でより顕著にするために、もっとPythonの理由がありますか?以下はなぜNotImplementedメソッドを持つ通常のクラスの代わりに抽象基本クラスを使用しますか?

は、私はそれが抽象的な「オプティマイザ」のインターフェイスを定義するために、私の「NotImplemented」スキームを実装して書いたコードスニペットです:

class AbstractOptimizer(object): 
    ''' 
    Abstract class for building specialized optimizer objects for each use case. 
    Optimizer object will need to internally track previous results and other data so that it can determine the 
    truth value of stopConditionMet(). 

    The constructor will require a reference argument to the useCaseObject, which will allow the optimizer 
    to set itself up internally using fields from the use case as needed. There will need to be a close coupling between 
    the optimizer code and the use case code, so it is recommended to place the optimizer class definition in the same module 
    as the use case class definition. 

    Interface includes a constructor and four public methods with no arguments: 

    0) AbstractOptimizer(useCaseObject) returns an instance of the optimizer 
    1) getNextPoint() returns the current point to be evaluated 
    2) evaluatePoint(point) returns the modeling outputs "modelOutputs" evaluated at "point" 
    3) scorePoint(evaluationResults,metric) returns a scalar "score" for the results output by evaluatePoint according to metric. NOTE: Optimization is set up as a MINIMIZATION problem, so adjust metrics accordingly. 
    4) stopConditionMet(score) returns True or False based on whatever past result are needed for this decision and the current score. If score = None, it is asumed to be the start of the optimization. 
    5) getCurrentOptimalPoint() returns currently optimal point along with its iterationID and score 

    The calling workflow will typically be: getNextPoint() -> evaluatePoint() -> scorePoint -> stopConiditionMet -> repeat or stop 

    ''' 


    def __init__(self, useCaseObject): 
     ''' 
     useCaseObject is a reference to use case instance associated with the optimizer. 
     This optimizer will be "coupled" to this use case object. 

     ''' 
     return NotImplemented 

    def stopConditionMet(self,score = None): 
     ''' 
     Returns True or False based on whether the optimization should continue.   
     ''' 
     return NotImplemented 

    def getNextPoint(self): 
     ''' 
     If stopConditionMet() evaluates to False, then getNextPoint() should return a point; otherwise, it should return None     
     ''' 
     return NotImplemented 

    def evaluatePoint(self,point): 
     ''' 
     Returns the modeling outputs "modelOutputs" evaluated at the current point. 
     Will utilize the linked 
     ''' 
     return NotImplemented 

    def scorePoint(self,evaluationResults,metric): 
     ''' 
     Returns a scalar "score" for the current results evaluated in at the current point (from evaluatePoint) based on the function "metric" 
     Note that "metric" will likely need to be a closure with the evaluation results as bound objects. 
     ''' 
     return NotImplemented 

    def getCurrentOptimum(self): 
     ''' 
     returns currently optimal point and it's score as a dictionary: optimalPoint = {"point":point,"score":score} 
     ''' 
     return NotImplemented 
+0

[NotImplementedError]、['NotImplemented'はPythonの比較メカニズムに関連する定数値です](https://docs.python.org/2/library/constants.html#NotImplemented)を呼び出す必要があります。それは意味論的意味が異なっている。 –

+0

@ŁukaszRogalskiありがとう!良いキャッチ...それはオーバーライドを強制します。上記をNotImplementedErrorsに変更すると、ABCについて何が欠けていますか?特にPython 2と3はこれを別の方法で扱いますから? –

+2

[ABCMetaから派生したメタクラスを持つクラスは、抽象メソッドとプロパティのすべてがオーバーライドされていない限りインスタンス化できません._ '__init__'だけをオーバーライドすれば、サブクラスがインスタンス化するのに十分です。 –

答えて

0

PEP 3119この

のすべての背後に合理的に説明し..さらに、ABCは、型の特徴的な振る舞いを確立する最小限のメソッドセットを定義します。 ABC型に基づいてオブジェクトを識別するコードは、それらのメソッドが常に存在すると信じることができます。これらのメソッドのそれぞれには、ABCのドキュメントに記述されている一般化された抽象セマンティック定義が付いています。これらの標準的な意味定義は強制されませんが、強く推奨されます。

これは重要な情報のようです。 AbstractBaseClassは、標準objectで保証されない保証を提供します。これらの保証は、OOPスタイルの開発におけるパラダイムに最も重要です。特に検査:一方

、古典的なOOPの理論家による検査の批判の一つは、形式主義の欠如、検査されているもののアドホックな性質です。 Pythonのように、オブジェクトのほとんどすべての側面が反映され、外部コードに直接アクセスできる言語では、オブジェクトが特定のプロトコルに準拠しているかどうかをテストするさまざまな方法があります。例えば、 'このオブジェクトは変更可能なシーケンスコンテナですか?'と尋ねると、 'list'の基本クラスを探すか、 'getitem'という名前のメソッドを探すことができます。しかし、これらのテストは明白なように見えるかもしれませんが、どちらも正しいとは言えません。偽のネガティブが生成され、他の誤検出も発生します。

一般的に合意された救済策は、テストを標準化して正式な配置にすることです。これは、継承メカニズムまたはその他の手段を使用して、各クラスに標準のテスト可能なプロパティのセットを関連付けることで最も簡単に実行できます。各テストには、クラスの一般的な振る舞いについての約束と、他のクラスメソッドが利用可能になることについての約束が含まれています。

このPEPでは、抽象基本クラス(ABC)と呼ばれるこれらのテストを構成するための特定の戦略を提案しています。 ABCはPythonクラスで、オブジェクトの継承ツリーに追加され、そのオブジェクトの特定の機能を外部のインスペクタに通知します。テストはisinstance()を使用して行われ、特定のABCの存在はテストが合格したことを意味します。

そうです、あなたはオブジェクトを使用してABCMetaクラスの振る舞いを模倣し、ABCのメタクラスのポイントは、それが定型を減らし、偽陽性、偽陰性、及びそのそうではないだろうコードについての保証を提供することができますしながら、開発者があなたの重労働を起こすことなく保証することができます。

+0

ありがとうマイク。これは役に立ちました! –

関連する問題