2021-03-11に投稿

Python クラスの定義 - class

Pythonでクラス(class)を定義する方法です。

クラスの定義

Pythonのクラスはキーワードclassを使って定義できる。
特別なメソッド__init__でインスタンス生成時の処理を定義できる。

class SampleClass:
    """クラスのサンプル""""

    def __init__(self, name):
        """コンストラクタ"""
        self.name = name

    def say(self):
        """サンプルのメソッド"""
        print(self.name)

インスタンスの生成はクラス名()で行う。

sc = SampleClass("taro")
sc.say() # => taro

クラス変数とインスタンス変数

クラス直下に記述した変数はクラスに属するスタティックな変数のようにアクセスできる。
self以下に定義した変数はインスタンス変数となる。

class SampleClass:
    static_list = [10, 20 , 30]
    def __init__(self):
        self.instance_list = []
    def add(self, item):
        self.instance_list.append(item)

sc1 = SampleClass()
sc2 = SampleClass()
sc1.add(1)
sc2.add(2)
sc1.static_list.append(40)
sc2.static_list.append(50)

# インスタンス変数は、インスタンス毎に値が保持される
sc1.instance_list # => [1]
sc2.instance_list # => [2]

# スタティック変数(クラス変数)は、クラスで共通する値として保持する
sc1.static_list # => [10, 20, 30, 40, 50]
sc2.static_list # => [10, 20, 30, 40, 50]

# クラス名.名称でアクセスできる
SampleClass.static_list # => [10, 20, 30, 40, 50]

ただし、同名のインスタンス変数を定義すると、
クラス変数が見えなくなってしまう。

sc1.static_list = ['a']
sc1.static_list  # => ['a']
sc2.static_list  # => [10, 20, 30, 40, 50]

継承

継承はクラス名の後に丸括弧で継承元のクラスを指定する事で行える。

class Animal:
    def __init__(self, weight):
        self.weight = weight

    def w(self):
        print(self.__class__.__name__, self.weight)

class Dog(Animal):
    pass

class Cat(Animal):
    pass

d = Dog(123)
c = Cat(77)
d.w() # => Dog 123
c.w() # => Cat 77

継承したクラスの初期化

class SampleClassBase:
    def __init__(self, name=""):
        self.name = name

class SampleClass(SampleClassBase):
    def __init__(self, name="", age=0):
        super().__init__(name)
        self.age = age

プライベート変数

Pythonでは、priavateといったキーワードで変数やメソッドを隠蔽する方法はない。

慣習的に、アンダースコアで始まるメソッドや変数は非公開として扱い、
特にアンダースコアを2つ重ねると自動で変数が難号化(mangle)されて公開される。

class SamplePriavate:
    def __init__(self, name):
        self.__name = name
    def say(self):
        print(self.__name)

sp = SamplePriavate("taro")
print(sp._SamplePriavate__name) # => "taro"
# print(sc.__name) # => AttributeError: 'SampleClass' object has no attribute '__name'

名称の置き換えは名前マングリング(name mangling)と言われ、_クラス名__変数名に置換される。

スタティックメソッド(static method)、クラスメソッド(class method)

インスタンスレベルでのメソッドではなく、クラスにメソッドを定義したい場合がある。

Pythonでは、メソッドにデコレータ@classmethod@staticmethodをつけることで実現できる。

@classmethodの場合、引数としてクラスclsが渡ってくるので継承する可能性がある場合はこちらが使える。

class StaticClassSampleBase:
    def instance_method(self, n):
        print(n)

    @classmethod
    def class_method(cls, n):
        print(cls, n)

    @staticmethod
    def static_method(n):
        print(n)

class StaticClassSample(StaticClassSampleBase):
    pass

scs = StaticClassSample()
scs.instance_method(1) # => 1

scs.class_method(2) # => <class '__main__.StaticClassSample'> 2
StaticClassSample.class_method(3) # => <class '__main__.StaticClassSample'> 3

scs.static_method(4) # => 4
StaticClassSample.static_method(5) # => 5
Originally published at marusankakusikaku.jp
ツイッターでシェア
みんなに共有、忘れないようにメモ

maru3kaku4kaku

Pythonこつこつ学習中。よく忘れる。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント