基本
大前提として、JAVAの様にクラス名 = ファイル名じゃなくて良い!
また、1ファイルに複数のクラスも記述できる。
[ROOT/myhoge.py]
class MyHoge( object ): ※基底クラスは必ず object を継承する ※必ずじゃないかも。。。
def __init__( self ) ※コンストラクタ ※引数 self はお約束!
self.foo = 0 ※変数の定義や、初期値の設定などなど。。
def myadd( self, a ): ※メソッドを記述する ※クラスのメソッドの第一引数には必ず self が必要!!
self.foo += a
return self.foo
@classmethod
def hoge(cls, a): ※クラスメソッドを記述する際はデコレーター必須(第一引数には必ず cls が必要!)
return a ※クラスメソッドは直接クラスから呼び出す事ができる(逆にインスタンスからは無理)
● クラスの呼び出し
from myhoge import MyHoge
hoge = MyHoge() ※new は不要なので注意!
name = 'MyHoge'
hoge =
globals()[
name]() ※文字列からオブジェクトを生成する方法
print( hoge.myadd( 10 ) )
【メモ】
pythonのクラスには[public][private]等の属性はありません。
全てがpublicの様なものです。
なので、前述のクラスでは以下の様にクラス外から直接クラスの変数にアクセスできます。
hoge.foo = 30
しかし、特殊な変数名、関数名として「__○○○」(アンダーバー2個)という変数、関数は外部からは参照も制御もできない private な変数、関数となります。
● 変数をプロパティにする
外部から直接変数を操作されない「__○○○」変数を参照、制御するために変数をプロパティにする事ができる
[ROOT/myhoge.py]
class MyHoge( object ):
def __init__( self )
self.__foo = 0 ※変数名を[__○○○]とする(アンダーバー付き)
@property
def foo( self ): ※プロパティ[foo]を定義する
return self.__foo ※[__foo]を返却するだけ。 ※@property属性の foo は、変数として参照できる
@foo.setter ※プロパティ foo に対して外部からの値の操作を可能とする
def foo( self, v ):
self.__foo = v ※変数 foo として制御できる
● デコレータ「@」を使わずに変数をプロパティにする
[ROOT/myhoge.py]
class MyHoge( object ):
def __init__( self )
self.__foo = 0
def
get_foo( self ):
return self.__foo
def
set_foo( self, v ):
self.__foo = v
foo =
property(
get_foo, set_foo) ※この設定で、変数 foo で参照も制御もできる
【注意】
この方法だと変数 foo でアクセスできるが、同時にメソッド get_foo() でもアクセスできる。
これを回避するには、メソッド名を「__get_foo()」とアンダーバーを2個使い private 属性にすれば良い!
※当然「foo = property(__get_foo, __set_foo)」と定義する事
サンプルClass1
[ROOT/bankaccount.py]
class BankAccount(object):
def __init__(self):
self._balance = 0
@property
def balance(self):
return self._balance
def deposit(self, amount):
self._update_balance(self._balance + amount)
def withdraw(self, amount):
self._update_balance(self._balance - amount)
def _update_balance(self, newBalance):
if newBalance < 0: ※残金が0未満の場合は、確定せずにエラーとする
raise ValueError
self._balance = newBalance
【メモ】
入出金を管理する簡単なクラスです。
入金:deposit
出金:withdraw
金額を扱う変数は[_balance]とし、なんちゃって private 属性にしています。
参照はプロパティ属性を設定した balance です。
また、実際に入出金を確定するメソッドがなんちゃって private 属性の[_update_balance]となります。
● クラス変数を定義する
クラス変数とは JAVA でいう、STATIC な変数です。
インスタンスの振る舞いとは無関係なクラス自体で管理する変数となります。
サンプルClass2
class
Hoge(object):
_count = 0
@classmethod ※クラス変数を制御するクラスメソッドである事を宣言する
def countUp(cls): ※引数の cls は必須!
cls._count += 1
print(cls._count)
def __init__(self,color):
Hoge.
countUp() ※コンストラクタでクラスメソッドを呼び出す
self.color = color
def getColor(self):
return self.color
h1 = Hoge('red') ※「1」が表示される
print(h1.getColor())
h2 = Hoge('green') ※前回の「1」を保持しているため「2」が表示される
print(h2.getColor())
h3 = Hoge('blue') ※前回の「2」を保持しているため「3」が表示される
print(h3.getColor())
● 動的にクラスにメソッドを追加する
既存のクラスに動的にメソッドを追加する事ができる
サンプルClass3
class Hoge:
pass ※クラスは何も定義しない
def foo1(): ※関数を用意
print('ぷぷぷ~')
def foo2(): ※関数を用意
print('ほげほげ')
h1 = Hoge() ※クラス Hoge のインスタンスを作成
h2 = Hoge() ※クラス Hoge のインスタンスを作成
h1.bar = foo1 ※動的に Hoge クラスにメソッド bar を追加し、その内容をメソッド foo1 とする
h2.bar = foo2 ※動的に Hoge クラスにメソッド bar を追加し、その内容をメソッド foo2 とする
h1.bar() ※「ぷぷぷ~」と表示される
h2.bar() ※「ほげほげ」と表示される
【メモ】
追加した変数やメソッドを削除するには None を代入するか、del 文を使う
例)
h1.bar = None
del h2.bar
クラスの継承
< サンプルClass1 >を拡張した例(入出金履歴機能を追加)
[ROOT/history_bank_account.py]
from bankaccount import BankAccount
class HistoryBankAccount( BankAccount ): ※BankAccountを継承する
def __init__(self): ※コンストラクタ
super(HistoryBankAccount, self).__init__() ※親のコンストラクタを実行する。
※引数はお約束かな。。
※(第一:自身のクラス名、第二:self)
self.history = [self._balance]
※リスト型変数historyを定義し、初期値に親クラス変数のbalanceを設定する
def _update_balance(self, newBalance): ※オーバーライドする
super(HistoryBankAccount,self)._update_balance(newBalance)
※処理自体は親クラスのメソッドに任せる。 super( 自身のクラス名, self ).親のメソッド名( 引数... )
self.history.append(self._balance) ※追加の処理として、履歴変数historyのリストをappendで追加する
【実は】
実は、super(HistoryBankAccount,self) 内の引数は全て省略可能です!
クラスの多重継承
class Hoge():
def __init__(self, name):
pass
class Foo():
def __init__(self, num):
pass
class Bar(Hoge, Foo): ※多重継承
def __init__(self):
Hoge.__init__(self, 'fuga') ※クラス Hoge を初期化する
Foo.__init__(self, 10) ※クラス Foo を初期化する
スペシャルメソッド
クラスをint,list,tuple,set,boolに変換した際の定義を設定できます
● int型への変換
class Hoge( object ):
def __int__( self ): ※[__int__]がスペシャルメソッド
return 10
a = Hoge()
print( int( a ) ) ※10となる
● イテレータ型(int,tuple,set)への変換
class Hoge( object ):
def __iter__( self ):
return iter( [ 1, 2, 3 ] )
a = Hoge()
print( list( a ) ) ※[ 1, 2, 3 ]となる
print( tuple( a ) ) ※( 1, 2, 3 )となる
print( set( a ) ) ※{ 1, 2, 3 }となる
● bool型への変換
class Hoge( object ):
def __init__( sef ):
self.foo = 10
def __bool__( self ):
return self.foo > 10
a = Hoge()
print( bool( a ) ) ※初期値のままなら 10 > 10 の状態なので False となる
● str型への変換
class Hoge( object ):
def __str__( self ):
return 'ほげふ~ばぁ'
a = Hoge()
print( str( a ) ) ※ほげふ~ばぁ