molpako.py

もるぱこのブログです

ダックタイピングって?

こんにちわ。もるぱこです。

何気なくいつものようにPythonの記事を眺めるためにネットサーフィンしていると、以下の記事で、

動的型付けで得るもの、失うもの。
最後の指摘は、動的型付けは得ることよりも失うものの方が大きい、というものです。
まず、得るものとは何か? について考えましょう。ここで僕が言えるのは、動的型付けではなくダックタイピング(注:ダック型付けと書くべきか?)をすべきということです

という記述がありました。

www.publickey1.jp

・・・ダックタイピングって???一度、オライリーの入門Python3でチラ見はしましたが、もう忘れて(そもそも理解していなかった)しまっていました。

今日はこのPythonにおけるダックタイピングについて勉強していきます。

ダックタイピングとは

まずは、Wikipediaさん曰く、

オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、たとえそのクラスがそのインタフェースを宣言的に実装していなくとも、オブジェクトはそのインタフェースを実行時に実装しているとみなせる
"If it walks like a duck and quacks like a duck, it must be a duck"
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)
ダック・タイピング - Wikipedia

らしいです・・・。つまりクラスの型が一致しているかどうかではなく、オブジェクトの関数や属性が適切かどうかで同じインターフェースを実装しているかのように振舞える。ということですかね。

それでは、サンプルコードを書いていきましょう。

書いてみる

class Dog:

    def __init__(self, name):
        self.name = name

    def sound(self):
        return 'ワンッ!'


class Duck:

    def __init__(self, name):
        self.name = name

    def sound(self):
        return 'クワッ!'


def test(animal):
    """属性nameと関数soundを使用するテストコード"""

    print('{}は、{}と鳴いた'.format(animal.name, animal.sound()))

上のクラスは「犬」のクラスです。属性は、nameをもっています。関数はsoundで引数はありません。 上のクラスは「アヒル」のクラスです。属性は、nameをもっています。関数はsoundで引数はありません。

では、上記ふたつのクラスのオブジェクトをtest()に与え実行してみましょう

実行結果

>>> test(Dog('もるぱこ'))
もるぱこは、ワンッ!と鳴いた

>>> test(Duck('もるぱこ'))
もるぱこは、クワッ!と鳴いた

OK!!

DogDuckは違うクラス(型)ですが、属性や関数が一致しているため互換性が取れていますね!

最後に

  • Python(動的型付け言語)では、ダックタイピングを行うこと
  • DogDuckは違う型なのでisinstance()type()での判別は避ける
  • 標準ライブラリabcを使用すればインタフェースの実装ができる

以上です!

最後まで見ていただきありがとうございました。これからもよろしくお願いします。