1

次のクラスがあるとします。

class Duck(object):
    pass

class OldFashionedDuck(Organism, Duck):
    def look(self):
        self.display_biological_appearance()
    def walk(self):
        self.keep_balance_on_two_feet()
    def quack(self):
        self.make_noise_with_lungs("Quack!")

class ArtificialDuck(Robot, Duck):
    def look(self):
        self.display_imitation_biological_appearance()
    def walk(self):
        self.engage_leg_clockwork()
    def quack(self):
        self.play_sound("quack.au")

この例では、OldFashionedDuck と ArtificialDuck に共通の実装はありませんが、構造上、どちらも isinstance(..., Duck) に対して True を返します。

これは完璧ではありませんが、ダックタイピングを尊重し、(空の mixin 継承を介して) isinstance() を許可するのに役立つかもしれないと私が考えたものです。本質的には、インターフェイスを満たすための契約を提供するため、すべての作業を行うクラスに基づいて実際に isinstance() を呼び出すのではなく、誰でもオプトインできるインターフェイスに基づいて呼び出します。

「isinstance() は有害と見なされる」に基づく記事を見たことがあります。ただし、少なくともプログラマーとして、オブジェクトがどこから関数を取得するかではなく、インターフェイスを実装しているかどうかを知りたいと思っています。

このアプローチは有用ですか? もしそうなら、それを改善できますか?

4

2 に答える 2

6

「isinstance() は有害と見なされる」に基づく記事を見たことがあります。ただし、少なくともプログラマーとして、オブジェクトがどこから関数を取得するかではなく、インターフェイスを実装しているかどうかを知りたいと思っています。

私はあなたが要点を逃していると思います。

「ダックタイピング」について話すとき、私たちが本当に意味するのは、インターフェースを形式化することではありません。したがって、あなたがやろうとしていることは、「インターフェイスを形式化せずにインターフェイスを形式化するにはどうすればよいですか?」という質問に答えようとすることに要約されます。

与えられたオブジェクトがインターフェースを実装することを期待しています - 基底クラスを作成するのではなく、たくさんのドキュメントを書き、動作を説明することによって記述したものです (特に気まぐれな場合は、何らかのテスト スイートの) - これは私たちが期待するものであると言ったからです (これもドキュメントで)。オブジェクトがインターフェイスを実装しているかのように使用し、結果として生じるエラーを呼び出し元の責任として扱うことによって、オブジェクトがインターフェイスを実装していることを確認します。間違ったオブジェクトを与えるコードを呼び出すのは悪いことであり、バグを修正する必要があるのはそこです。(繰り返しますが、テストはこれらを追跡するのに役立ちます。)

要するに、テストは実際にisinstance(this_fuzzball_that_was_handed_to_me, Duck)は役に立ちません。

  • チェックに合格してもisinstance、期待に反する方法でメソッドを実装する可能性があります (または、たとえばreturn NotImplemented)。ここでは実際のテストのみを行います。

  • チェックに合格する可能性がありますが、実際には 1 つ以上のメソッドの実装に完全に失敗します。結局のところ、ベースにDuckは実装が含まれておらず、Python には派生クラスでそれらをチェックする理由がありません。

  • おそらくもっと重要なのは、ダックとして完全に使用できるファズボールであっても、チェックに失敗する可能性があることです. おそらくそれは、関連のないオブジェクトでありquack、 、walkおよびlook関数が属性として手動で手動でアタッチされている可能性があります(ルックアップ時にメソッドになるクラスの属性とは対照的です)。

さて、「そんなことはやめて」とあなたは言います。しかし今、あなたは皆のためにより多くの仕事をしています。クライアントが常にオプトインするとは限らない場合、アヒルを使用するコードがチェックを行うのは無意味で危険です。その間、あなたは何を得ていますか?

これは EAFP の原則に関連しています。何かを見てダックかどうかを判断しようとしないでください。それをアヒルとして扱い、そうでない場合は悲惨な混乱に対処することで、それがアヒルであるかどうかを判断します。


しかし、ダックタイピングの哲学を気にせず、物事にある程度の厳密さを強制する必要がある場合は、標準ライブラリabcモジュールに興味があるかもしれません.

于 2013-01-21T09:08:59.980 に答える
1

この用語を過大評価したくはありませんが、あなたのアプローチはpythonicではありません。ダックタイピングをするか、しないか。

「インターフェース」の実装がすべてを実装していることを確認したい場合は、テストしてください。

小規模なプロジェクトの場合、必要なものを覚えておくのは簡単です。そして、あなたはそれを試すことができます。

大規模なプロジェクト、またはチームでの協力の場合でも、タイプに必要なものがすべて揃っていることを確認する方がよいことに同意します。このようなシナリオでは、単体テストを使用して型が完全であることを確認する必要があります。ダックタイピングがなくてもテストは必要なので、追加のテストはおそらく必要ないでしょう。

Guido van Rossum は、この講演でダックタイピングに関する興味深い考えについて語っています。とても刺激的で、一見の価値があります。

于 2013-01-21T09:17:44.540 に答える