「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。

MENU

Pythonをゆっくりていねいに学ぶ(その14/X)

 Pythonを真面目にゆっくり学ぶべく

を参考に学んでいきます*1

6. オブジェクトとクラス

6.3 継承

 コーディング上の問題解決において、既存のクラスで必要なことを殆どしてくれるオブジェクトが作成できる際に便利なのが継承である。すなわち使いたい既存のクラスを指定し、追加ないし変更したい一部のみを定義した新しいクラスを作る。これによりメンテナンスしなければならないコードを省略できる。
 こうして継承した新たなクラスでは、古いクラスの動作は使われない(オーバーライド)。

6.3.2 selfの自己弁護

 インスタンスメソッド(これまでの例で作成したメソッド)の第一引数として\mathrm{self}を組み込まなければならないことは度々\mathrm{Python}の欠点として批判されることがある。\mathrm{Python}はこの\mathrm{self}引数を用いて適切なオブジェクトの属性とメソッドを見つけてくる。

class Car():
    def exclaim(self):
        print("I'm a car!")
        
car = Car()
car.exclaim()

 上記の例において\mathrm{Python}

  • \mathrm{car}オブジェクトのクラス(\mathrm{Car})を探し出す。
  • \mathrm{Car}クラスの\mathrm{exclaim}()メソッドに\mathrm{self}引数として\mathrm{car}オブジェクトを渡す。

という動作を行う。

6.4 プロパティによる属性値の取得、設定

 オブジェクト指向言語の中には、クラスの中に外部から直接アクセスできない非公開なオブジェクト属性をサポートしている場合がある。\mathrm{Python}は基本的にすべての属性とメソッドは公開であるものとして書くことが前提となっている。ただしプロパティを設定することで\mathrm{getter},\mathrm{setter}に相当するものを設定することはできる。
 プロパティはデコレーターで定義することもできる。

\mathrm{@property} ゲッターメソッドの前に付けるデコレーター
\mathrm{@name.setter} セッターメソッドの前に付けるデコレーター
########################
### プロパティの設定 ###
########################

# hidden_nameを非公開にしたい属性とする
class Duck():
    def __init__(self, input_name):
        self.hidden_name = input_name
    def get_name(self):
        print('inside the getter')
        return self.hidden_name
    def set_name(self, input_name):
        print('inside the setter')
        self.hidden_name = input_name
    name = property(get_name, set_name)

# 
fowl = Duck('Howard')
fowl.name

fowl.get_name()

fowl.name = 'Daffy'

fowl.name

##########################################
### デコレーターによるプロパティの設定 ###
##########################################

class Duck():
    def __init__(self, input_name):
        self.hidden_name = input_name
    @property
    def name(self):
        print('inside the getter')
        return self.hidden_name
    @name.setter
    def name(self, input_name):
        print('inside the setter')
        self.hidden_name = input_name

#
fowl = Duck('Howard')
fowl.name

fowl.name = 'Donald'
fowl.name

 プロパティには、属性の直接アクセスよりもメリットがある。プロパティの定義を書き換えても、クラス定義内のコードを書き換えるのみで済み、呼び出し元には手を付ける必要がないことである。

##########################################
### デコレーターによるプロパティの設定 ###
##########################################

class Circle():
    def __init__(self, radius):
        self.radius = radius
    @property
    def diameter(self):
        return 2 * self.radius
#
c = Circle(5)
c.radius
c.diameter

# 属性は自由に書き換えられる
c.radius = 7
c.diameter

# セッターを指定しなければ外部からプロパティを設定できない
c.diameter = 20

6.5 非公開属性のための名前のマングリング

 クラス定義の外からは見えないようにするクラス属性には__(アンダースコア2つ)を名前の先頭に付ける。
 この命名方法を用いると、偶然にプロパティをアクセスしないように\mathrm{Python}はマングリングをする。

####################
### マングリング ###
####################

class Duck():
    def __init__(self, input_name):
        self.__name = input_name
    @property
    def name(self):
        print('inside the getter')
        return self.__name
    @name.setter
    def name(self, input_name):
        print('inside the setter')
        self.__name = input_name

#
fowl = Duck('Howard')
fowl.name
fowl.name = 'Donald'
fowl.name

fowl.__name

*1:第2版が出ているものの初版しか持っていないのでこちらで。

プライバシーポリシー お問い合わせ