web-dev-qa-db-ja.com

動的なディスパッチとアヒルのタイピングとは何ですか?

Pycharmを使用する場合、次のようにエラーを指摘することがよくあります。

未解決の参照 'name'。この検査は、解決する必要があるが解決しない名前を検出します。 動的ディスパッチとアヒルのタイピングにより、これは限られているが有用なケースの場合に可能です。最上位およびクラスレベルのアイテムは、インスタンスアイテムよりも適切にサポートされます。

私はこれについてスヌープしましたが、私が見つけるほとんどの質問と情報は、メッセージが表示されないようにすることです。私が知りたいのは:

  • 動的ディスパッチ/ダックタイピングとは何ですか?
  • これらの「有用なケース数」とは何ですか(またはその例)。
8
Rick M.

Pythonはアヒルのタイピング規則を使用します。つまり、名前のタイプを指定する必要はありません。たとえば、Javaの場合とは異なり、変数はintまたはObject型であることを明示的に指定する必要があります。基本的に、型チェックは実行時に行われます。

「それがアヒルのように歩き、それがアヒルのように鳴るなら、それはアヒルでなければなりません。」

In Pythonは、オブジェクトが設計されていない方法でオブジェクトを操作しようとするまで、すべて動作するように見えます。基本的に、オブジェクトには、そして、あなたはPythonがそれを試みるとエラーを投げるまでこれを見つけられません。

動的ディスパッチは、実行時に使用する多態性関数のバージョンを選択するコンパイラまたは環境の実践です。メソッドの実装が複数ある場合は、メソッドが同じまたは類似のプロパティ/属性を持っているにもかかわらず、異なる方法でそれらを使用できます。以下に例を示します。

_class Foo:
   def flush():
       pass

class Bar:
    def flush():
       pass
_

両方のクラスにはflush()メソッドがありますが、実行時に正しい名前が選択されます。

メソッドは複数のパラメーターを取ることができ、再実装する必要がないため、Pythonはこのプロセスの最良の例ではありません。 Javaはより良い例ですが、私は正しい例を提供するのに十分に流mではありません。

6
smallpants

警告は、PyCharmが認識しない変数を使用していることを意味しますが、Pythonの動的な性質のため、正しいかどうかはわかりません。

たとえば、次のコードがあります。

class myClass():

    def myfunc(self):
        print(self.name)

PyCharmはおそらくself.name解決できません。ただし、次のようにクラスを使用できます。

my_class = myClass()
my_class.name = "Alastair"
my_class.myfunc()

これは完全に有効です(脆弱ではありますが)。

メッセージは、属性とメソッドがより曖昧ではないことに自信を持っていると言い続けています。例えば:

class myClass():
    my_instance_var = "Al"

    def myfunc(self):
        print(self.my_instance_var)

my_instance_varはソースコード(クラス属性)で定義されており、PyCharmはそれが存在することを確信できます。

(何をしているのかわからない限り、クラス属性を使用しないでください!)

4