Python基礎❸

# サードパーティーパッケージの導入

Pythonでは、標準だけでもさまざまな機能があるが、インターネット上で個人や企業が公開している「サードパーティ製パッケージ」を追加して様々な便利な機能を使うことができる。
❶メニューからpreference
❷pythonインタープリターで＋ボタンをクリック
❸入れたいパッケージを検索
❹コマンドラインでpipでも可能

Python公式ドキュメント→

```main.py
from termcolor import colored

print('test')

print(colored('test', 'red'))

```
# __name__と__main__

```main.py
print(__name__)//このスクリプトを実行しているメインのスクリプトですと表示してくれる→__main__
```


```lesson_package/talk.py
print(__name__)
```

```main.py
from lesson_package.talk import animal

print(__name__)

/*
animal: lesson_package.talk.animal→メインではない方は、ファイル名が表示される。
__main__ →main.py内の処理
*/
```
`if __name__=='__main__':`→インポートされた際に実行されない。

https://blog.pyq.jp/entry/Python_kaiketsu_180207
→ありがとうございます。

# クラスの初期化とクラス変数

+ クラスのメソッド引数には、`self`を入れる。selfはインスタンス自身を指す。
+ `__init__`→コンストラクタという。インスタンスが作成された時に最初に呼び出されるもの。

https://www.sejuku.net/blog/28182
上記のサイトがわかりやすかったです。ありがとうございます。

```main.py
class Person(object):
    def __init__(self, name):
        self.name = name
        
    def say_something(self):
        print('I am {}. hello'.format(self.name))
        self.run(10)

    def run(self, num):
        print('run' * num)

person = Person('Mike')
person.say_something()
```
# コンストラクタとデストラクタ

+ `デストラクタ`→オブジェクトが破棄されるときに呼び出されるメソッド

```main.py
class Person(object):
    def __init__(self, name):
        self.name = name

    def say_something(self):
        print('I am {}. hello'.format(self.name))
        self.run(10)

    def run(self, num):
        print('run' * num)

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

person = Person('Mike')
person.say_something()
del person//呼び出す
print('#############')

```
# クラスの継承

```main.py
class Car(object):
    def run(self):
        print('run')//元となるメソッドを記す

class ToyotaCar(Car):#引数に上のクラス（Car）を入れる。→継承
    pass

class TeslarCar(Car)://Carの基本的なrunの役割を継承している。
    def auto_run(self)://テスラーカーのみの役割
        print('auto_run')

car = Car()
car.run()

toyota_car = ToyotaCar()
toyota_car.run()

tesla_car = TeslarCar()
tesla_car.auto_run()
tesla_car.run()#Carを継承しているため、Carのメソッドも使える。

```
# メソッドのオーバーライド

メソッドも上書きが可能

```main.py
class Car(object):
    def __init__(self, model=None)//modelは車の名前
　　　　　　　self.model = model
    def run(self):
        print('run')//元となるメソッドを記す

class ToyotaCar(Car):#引数に上のクラス（Car）を入れる。→継承
    pass

class TeslarCar(Car)://Carの基本的なrunの役割を継承している。
    def run(self)
        print('super fast')//メソッドを上書き
    def auto_run(self)://テスラーカーのみの役割
        print('auto_run')

car = Car()
car.run()

toyota_car = ToyotaCar()
toyota_car.run()

tesla_car = TeslarCar('lexus')
print(resla_car.model)
tesla_car.auto_run()
tesla_car.run()
```
+ `super`で継承

```main.py
class Car(object):
    def run(self):
        print('run')

class ToyotaCar(Car):#引数に上のクラス（Car）を入れる
    pass

class TeslarCar(Car):
    def __init__(self, model="Model S", enable_auto_run=False):#enable_auto_run=Falseは実行しないということ
        # self.model = model//Carクラスとかぶってしまうため、superで継承
        super().__init__(model)
        self.enable_auto_run = enable_auto_run//Tesla_Car専用のメソッド
    def auto_run(self):
        print('auto_run')

```
# プロパティ

+ 勝手にメソッドを書き変えられたくない時は、プロパティ、アンダースコアを使う
+ プロパティはある条件に合致したときだけ書き換えていいというもの。
+ アンダースコア2個の場合は、クラス内ではアクセスできるが、一度オブジェクトを作成するとアクセスできない。
+ アンダースコア1個の場合は、外部からいじってほしくないことを明示的に示している。

```main.py
class Car(object):
    def __init__(self, model=None):
        self.model = model
    def run(self):
        print('run')

class TeslarCar(Car):
    def __init__(self, model="Model S", enable_auto_run=False):
        super().__init__(model)
        self._enable_auto_run = enable_auto_run//アンダースコアで明示的にいじってほしくないことを表している。

    def auto_run(self):
        print('auto_run')

    @property#読み込みはできるけど設定（書き換え）はできない。
    def enable_auto_run(self):
        return self._enable_auto_run//アンダースコアにした値を返す。

    @enable_auto_run.setter#書き込みを可能にする。→@propetyをつけたものに対して、setterをつける。
    def enable_auto_run(self, is_enable):
　　　　　if self.passwd = '456':
            self._enable_auto_run = is_enable
        else:
            raise ValueError
       
tesla_car = TeslarCar('Model S', passwd = '456')//456だとTrueに書き換えられる。
tesla_car.enable_auto_run = True//Trueに置き換える。ただプロパティにするとエラーになる。
print(tesla_car.enable_auto_run)//プロパティでも読み込むことはできる

```
# ダックタイピング

:::note
adultの時
❶adultクラスが生成された時に、Adultの__init__でデフォルト引数が18なので、そのまま18をスーパークラスに渡す。Personのオブジェクト（親）に渡す。
❷self.ageが18になる。
❸car.ride(adult)にわたし、ride(self, person)のpersonにわたし、driveを実行する。
:::
```main.py
class Person(object):→personというオブジェクト
    def __init__(self,age=1):
        self.age = age
    
　　def drive(self):
        if self.age >= 18:
            print('ok')
        else:
            raise Exception('No drive')

class Baby(Person):
    def __init__(self, age=1):
        if age < 18:
            super().__init__(age)
        else:
            raise ValueError

class Adult(person):
    def __init__(self, age = 18):
        if >= 18:
            super().__init__(age)
        else:
            raise ValueError

baby = Baby()
adult = Adult()


class Car(object):
    def __init__(self, model=None):
        self.model = model
    def run(self):
        print('run')

    def ride(self, person):#人を乗せる→そしてその人はドライブするという処理
        person.drive()

car = Car()
car.ride(baby)//No drive
car.ride(adult)//ok

```
# 抽象クラス

+ `抽象クラス`→「継承したクラスで実装してください」ということ。
+ 下記のように書くことによって、driveというメソッドは、Personというオブジェクトを継承したクラスで必ず定義してあげないとエラーになる。
```main.py
import abc

class Person(metaclass=abc.ABCMeta)//抽象クラスであることを表す。
    def __init__(self,age=1)
       self.age = age

　　@abc.abstractmethod//継承するクラスで必ずdriveメソッドを使う
    def drive(self):
        pass
```
# 多重継承

```main.py
class Person(object):
    def talk(self):
        print('talk')

    def run(self):#PersonCarRobotの引数に入れた順（左を優先）とする。
        print('person run')

class Car(object):
    def run(self):
        print('run')

class PersonCarRobot(Person, Car):#二つ継承
    def fly(self):#PersonCarRobotだけにあるメソッド
        print('fly')

person_car_robot = PersonCarRobot()
person_car_robot.talk()
person_car_robot.run()
person_car_robot.fly()
```
# クラスメソッド

```csharp:main.py
class Person(object):
    kind = 'human'#グローバル変数みたいなもの

    def __init__(self):
        self.x = 100# selfは自分自身→オブジェクトが生成されていなければアクセスできない。

        @classmethod#オブジェクトとして生成されていなくてもアクセスできるようにする。
        def what_is_your_kind(cls):
            return cls.kind
a = Person()#()をつけてオブジェクトにしている
print(a.what_is_your_kind())

b= Person
print(b.what_is_your_kind())
print(Person.kind)

```
# 特殊メソッド

`特殊メソッド`→アンダースコア2個あるもの 

# ファイルの作成
https://office54.net/python/basic/python-textfile-create
上記のサイトを参考にさせていただきました。ありがとうございます。

# withステートメントでファイルをopenする

+ `withステートメント`→closeがなくても、最後に自動的にcloseしてくれる。

```csharp:main.py
with open('test.txt', 'w') as f:
    f.write('Test\n')
    print('I', 'am', 'print',sep='#', end='!', file=f)
```
# ファイルの読み込み


```csharp:main.py
s = """\
AAA
BBB
CCC
DDD
"""
with open('test.txt', 'r') as f://r→読み込み
    print(f.read())//text.txtファイルを読み込む→read

```
+ 1行ずつ読み込むこともできる
https://code-graffiti.com/create-and-load-file-in-python/
上記のファイルを参考にさせていただきました。ありがとうございます。

```csharp:main.py
s = """\
AAA
BBB
CCC
DDD
"""
with open('test.txt', 'r') as f:
    # print(f.read())
    while True://繰り返し
        line = f.readline()//readlineで1行ずつ読み込む
        print(line, end='')//printで出力されると改行されるため、end = ''で改行をなくす。
        if not line://繰り返しが終われば、ループを抜ける。
            break

```
# seek

`tell`→tell()を使うと、現在の位置が先頭からどの位置にあるのかがわかる。 

# 書き込みプラス読み込み

モード→w+で書き込みプラス読み込み

```csharp:main.py
s = """\
AAA
BBB
CCC
DDD
"""
with open('test.txt', 'w+') as f:
    f.write(s)//書き込み
    f.seek(0)//最初に戻る
    print(f.read())//読み込み

```
+ r+→読み込んだ後に書き込む

``````csharp:main.py
s = """\
AAA
BBB
CCC
DDD
"""
with open('test.txt', 'r+') as f:
    print(f.read())
    f.seek(0)
    f.write(s)
```
# テンプレート