Python 初級入門 オブジェクトとクラス編

- python初学者、触ったことない人が投稿しています
- 個人的にあまり馴染みのない書き方について記載しています
- 誤っている箇所等があればコメントでご指摘いただけると幸いです
- こちらの記事は[パッケージとモジュール編](https://qiita.com/takemaru_shuna/items/f4ba304674a859a8b3f2)の続きとなっていますので気になる方は是非！


では早速本編へ

## クラス
### クラスの初期化、定義、デストラクタ
- classの定義
    - Person # python３から
    - Person()
    - Person(object) 
- クラスの初期化`__init__`が呼ばれる（コンストラクタみたいな？？）
- クラスが呼ばれん空くなったタイミングでデストラクタ`__del_`_が呼ばれる
```.py
class Person:
    def __init__(self,name):
        self.name = name
        
    def greeting(self):
        print(f'I am {self.name}. hello')

    def __del__(self):
        print('bye')

person = Person('Mike')
person.greeting() # I am Mike. hello

del person # 明示的にdelをコール
```

### クラスの継承
- クラス定義で継承するクラスを渡す
    - `()`に親クラスを渡す
- メソッドのオーバーライド
    - `super()`で親の関数を呼び出して、特定のクラスでのみ使用する処理を追加できる
- プロパティを使って属性の設定
    - `_`にはプライベートな意味合いがある
    - `__`はクラス内からの参照しか許容しない
    - @propertyを設定したもの
        - 呼び出す際に()は不要
        - 外から呼び出した際に値を代入することは不可
        - 書き換え可能にする場合はsetterを設定する
        - 基本的に何か条件を加えて、setterを動くようにするのがメジャー
```.py
class Car(object):
    def __init__(self,model= None):
        self.model = model
        
    def run(self):
        print('run')

class ToyotaCar(Car): # クラスの継承
    pass

class AutoCar(Car)
    def __init__(self,model= 'hoge',is_run=False):
        super().__init__(model) # オーバーライド
        self.isRun = is_run

    #ここ単体だと値の設定は不可
    @property 
    def is_run(self):
        return self.is_run 

    # 値を設定する際は以下も必要
    @is_run.setter
    def is_run(self,is_run):
        if seld.model == 'crown'
            self.is_run = is_run

    def auto
        print('auto')

toyota = ToyotaCar('crown')
print(toyota.model) # crown
toyota.run() # run

autoCar = AutoCar('auto-fast')
print(autoCar.model) # auto-fast
autoCar.run() # run
autoCar.auto() # auto
```

### 抽象クラス
- 抽象クラスのメソッドを必ず実装してほしいメソッドを`@abc.abstractmethod`で使用できる
- 作る必要がなければ作らない方がいいかも
    - 元々なかったからあまり推奨されていない？
```.py
import abc

class Person(metaclass = abc.ABCMeta): # 抽象クラス
    def __init__(self, age = 1):
        self.age = age

    @abc.abstractmethod
    def say_hello(self):
        pass

class Adult(Person):
    def __init__(self, age = 20):
        if (self.age >= 20):
            super().__init__(age)
        else:
            raise Exception

adult = Adult()

```

### 多重継承クラス
- 複数継承してクラスを定義
    - `Robot(Person,Car)`みたいな場合は`Person`に定義されているものから優先的に使われる
    - メソッド名とかが被った場合は左のclassから評価される
- 最初からわかっているなら使うべきではない
```.py
class Person(object):
    def __init__(self, name = 'taro'):
        self.kind = 'human'
        self.name = name

    def who_are_you:
        print(self.name, self.kind)

a = Person(a)
a.who_are_you() # a, human

```

### クラスメソッドとスタティックメソッド
- クラスメソッドはインスタンス化していなくてもアクセスが可能
```.py
class Person():
    age = 20
    def __init__(self):
        self.a = 100

    @classmethod
    def how_old(cls):
        return cls.age

    @staticmethod
    def about(year):
        print(f'about human {year}')

a = Person() # object
b = Person 

print(a.a) # 100
print(b.a) # error

# オブジェクトになっていなくてもアクセスできる
print(a.how_old) # 20
print(b.how_old) # 20

print(a.age) #20
print(b.age) #20

Person.about(1000) # about human 1000
```

### 特殊メソッド
- `__`が特殊メソッドに該当する
- 一覧
    - [公式](https://docs.python.org/ja/3/reference/datamodel.html#special-method-names)を参照

```.py
class Hoge(object):
    def __init__(self,piyo):
        self.text = text

    def __str__(self):
        return 'foo'

h = Hoge('ppp')
print(h)

```


## 最後に
- なんかpython3とかで新たに付け加えられても2の方が浸透してるからみたいな感じで新しいものが使われてない感じがする。これに関しては深く調べてないのでただの感想でしかないです
- 便利な反面の副作用的なところを意識しないといけないことが多い気がする
- 次回はファイル操作等について学んでみようと思います
- 次の次は。。。