python 脱チュートリアル2?
本日は、娘の幼稚園の入園願書受付ため徹夜で並ぶ。
バッテリーがあと2時間しかないが、その間に、
python の勉強をすることとした。
今日の課題は、クラス。現在、インターネットにつなげないの
で、ほかの python プログラムを見てまねっこ中です。
ということで、以前から気になっていた、クラスの使い方に
初チャレンジです。
(1) ただのクラスの作成
インスタンスの作り方に迷いながらなんとかクリア。
|
TEST_DEF = 10 class TestClass: def __init__(self): def Print(self, strName): def Print(self):
# not accessed. # accessed. # The overload test. |
(a) データメンバの可視性
チュートリアル中で書いてあったような気がしたのでトライ。
"__メンバ名" と記述するらしい。
C++ でいう public と protected といったところか。。
継承時の可視性はそこでテストすることにしよう
(b) 関数のオーバーロード
残念ながら、オーバーロードは実現されていないようだ。
スクリプトの最後に記述された関数が有効となってようで、
引数のタイプが違うといっておこられてしまう。
TypeError: Print() takes exactly 1 argument (2 given)
(2) テンプレートクラスの作成
C++ のテンプレートのようなクラスを作成してみました。
最初は、オブジェクトを渡すタイプを試みて見ました。
こちらは、すんなり動いて、これならつかえるかな。。
(3) 本当のテンプレートクラスの作成
と、思いつつ、ぜんぜんスマートでわないので、ちょっと
考えました。
。。。
もしかして、クラス名を渡すことができるのでは。。
|
# It like a template class. # template argument sample class 1. def PrintDataImpl(self, strName): # template argument sample class 2. def PrintDataImpl(self, strName): # template class sample : set a object to constructor def AddData(self, strName, strData): def PrintData(self, strName): # template class sample : set a class name to constructor def PrintData(self, strName): # test (1) cDataHolder = DataHolder(cDataHolderImpl1) cDataHolder2 = DataHolder(cDataHolderImpl2) # test (2) |
参考書がないので、とりあえず試してみることにした。
なんと、すんなり動くではありませんか。。
多分、基本中の基本のやり方なのかもしれませんが、
ちょっとうれしい。。
(4) クラスの継承
本来なら、(2) や (3)より先にこっちだろという突っ込み
が入りそうだがとりあえず。。できることより、できるかどうか
を確認してみたいということで。。。
で、クラスの継承のテストをやってみました。。
|
class SuperClass: def __init__(self): def Print(self):
# The overwrite test. # call super class method. set self argument at first.
|
(a) データメンバの可視性
スーパークラスの非公開メンバは継承したクラスからは
アクセスできるようだ。
(b) オーバーライドテスト
オーバーライドは問題なさそう。
スーパークラスの呼び出しも、self を渡せば大丈夫なようですね。
C++ の規定クラスのメソッドより呼び出しよりも直感的な感じ。。
(5) クラスの多重継承
オブジェクト指向言語では、多重継承が可能な言語が多い。
複数の同じ規定クラスのクラスを多重に継承したときに、意図されて
以内動きをする可能性があることから、多重継承はあまり推奨されて
いないが、そこをあえて、テストして使い勝手をみてみよう。。
|
# sample super class A def __init__(self): def Print(self): # sample super class B def __init__(self): def Print(self):
def Print(self):
|
(1) スーパークラスの呼び出し
スーパークラスを指定するのだから、当然問題なく行えた。
(2) スーパークラスの同名メソッドを呼び出し
先に定義したスーパークラスの呼び出しが行われる。
(3) オーバーライドした場合
あたりまえだが、ちゃんとオーバーライドしたものが呼ばれる。
まだ、ダウンキャストや、本当の多重継承での問題に直面していないので
今の段階では、問題ないと思う。
多重継承しなければならない場合は、設計段階で問題点を解決してから
実装すればすむことなので、そんなに気にすることはなさそうだ。
(6) モジュールの作成
クラスができたので、(別にクラスなくともよいと思うのですが、、)
モジュールを作成してみたいと思います。
モジュールといってもただファイル名を Import 節で記述するだけの
ようです。モジュール内のクラスを使用するためには、
|
Import モジュール名 Import モジュール名 as エリアス名 |
として、エリアス名でアクセスすることができます。モジュールの
検索パスですが、一般的な カレントディレクトリを検索して、
次に path 指定かと思いますが仕様を確認してみる必要があります。
from は、定数をインポートするときに指定します。
|
from モジュール名 import 定数名, ... |
固定値等の import を明示的に行う場合は定数名をカンマで区切って
羅列すればよいのですが、すべてをインポートするときは、"*" にします。
|
from モジュール名 import * |
ヘッダファイル的な使い方ができるので便利そうです。この定数を
使用するときは "モジュール名.○○" ではなく、定数名をそのまま使用
できるのですが、C++ のネームスペースの役割を果たす場合は、
ということで、バッテリーが切れそうなので今日はここまでにしたい
と思います。