Pythonでポリモーフィズムる

多様性?

趣味でPythonをやっている者でしたが、業務でちょっとしたツールをPythonで作ることになり晴れて趣味から「業務での実績あり!」と言えるようになりそうです。
まぁツールといっても別の誰かが作った別のツール的な何かをうまいこと叩けるようにするだけのものだし、やはり趣味の延長でしかないという気が(誰もレビューしてくれないし)

何はともかくやるのである。
別のツール的な何かはいくつかあり、Python実行時の引数でどのツール動かすか切り替えるかーと、でもいちいちメソッド呼び変えるのはなんかダサいよなー、えーとたしか同じメソッドで動きだけ変わるようなやつあったよなー、そうそう確かポリモーフィズム!

ここでタイトル回収(長い)
ポリモーフィズムって何?って方はちょっと説明する気合が今ないので調べてくださいね・・・
多様性の時代だしポリモーフィズム使わないとね!
(あれ、多態性だっけ?)

しかし趣味でPythonやっていた者なのでそもそも継承とかそういった概念があるのかすら認識しておらず・・・ググりました。あぁできるのね。

というわけでサンプルコードを書く
いいネタ思いつかなかったのでよくある動物系にします

まずは抽象クラスから
一応鳴く用の抽象メソッド(cry)を用意しときます。呼ばれても何もしない(してもいい)

animal.py
1
2
3
4
5
6
7
8
from abc import *
 
class Animal(metaclass = ABCMeta):
 
    @classmethod
    @abstractmethod
    def cry(cls):
        pass

Pythonで抽象クラスを扱うにはabcライブラリを使います。
Python3に組み込まれているのでpipとかで追加インストールは不要だぞ
あんまよくわかってないけどクラス定義にmetaclass = ABCMetaを渡してやることでこのクラスが抽象基底クラスと定義されるようです
抽象メソッドは今回クラスメソッドとしたので@classmethod, @abstractmethodのデコレータを付与します(順番大事!)

はい次、抽象クラスを継承したクラスを実装します

dog.py
1
2
3
4
5
6
7
from animal import Animal
 
class Dog(Animal):
 
    @classmethod
    def cry(cls):
        print("ワンワン!")
cat.py
1
2
3
4
5
6
7
from animal import Animal
 
class Cat(Animal):
 
    @classmethod
    def cry(cls):
        print("ニャー!")

cryメソッドのprint文変えてるだけなので特に解説はなし

最後にこれらのクラスを呼びだす処理

zoo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import sys
 
from dog import Dog
from cat import Cat
 
args = sys.argv
if args[1] == "いぬ":
    animal = Dog
elif args[1] == "ねこ":
    animal = Cat
else:
    sys.stderr.write('そんな動物はいません!')
    exit(1)
 
animal.cry()

テキトーですがコマンドラインの引数によって代入するクラスを変えることで鳴き声が変わるようにしてます

実行結果はこんな感じ

c:\work\test>python zoo.py いぬ
ワンワン!

c:\work\test>python zoo.py ねこ
ニャー!

c:\work\test>python zoo.py とり
そんな動物はいません!

引数なしで実行すると死ぬのはサンプルコードということでご容赦を
業務でやってるほうはまだ全部終わってないけど、このサンプルコードのように引数で使うクラスを切り替えてツール実行させるようにしてます

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA