ハードウェア技術者のスキルアップ日誌

某家電メーカーの技術者がスキルアップのために勉強したことを記録するブログです

Python入門 ー 個人的メモ

以前AidemyでPython入門を受講しましたが、YOLOなどのサンプルコードを
読んでいく中で自分の理解が足りなかった部分を改めて勉強しましたので、
学んだことを個人的な備忘録として記録しておきます。

まとめ方が悪い、見難い部分があると思いますがご了承ください。

Pythonの勉強には「みんなのPython」という本を使用しました。 

みんなのPython 第4版

みんなのPython 第4版

 

 

目次

 

ディクショナリー

キーと値で要素を管理(順番は関係なし)  ※リストには順番がある

f:id:masashi_k:20190331170908p:plain

●定義方法

ディクショナリ名={キー1:値1, キー2:値2, ・・・}

 ●値の取り出し方

ディクショナリ名[要素のキー]

 ●要素の入れ替え

ディクショナリ名[要素のキー] = 値   # 代入と同じ形

 ●新しい要素の追加

ディクショナリ名[新しいキー名] = 値   # 代入と同じ形

 
Tips

in演算子でディクショナリの中のキーを検索できる

def convert_number(num):
      # アラビア数字とローマ字の変換 対応表をディクショナリに定義
      roman_nums = {1:"Ⅰ", 2:"Ⅱ", 3:"Ⅲ", 4:"Ⅳ", 5:"Ⅴ",
                    6:"Ⅵ", 7:"Ⅶ", 8:"Ⅷ", 9:"Ⅸ"}
      if num in roman_nums:
                return roman_nums[num]
      else:
                return "[変換できません]"


for文にディクショナリを添えると繰り返し変数にキーを代入しながらループを実行する

# アラビア数字とローマ字の変換 対応表をディクショナリに定義
roman_nums = {1:"Ⅰ", 2:"Ⅱ", 3:"Ⅲ", 4:"Ⅳ", 5:"Ⅴ",
              6:"Ⅵ", 7:"Ⅶ", 8:"Ⅷ", 9:"Ⅸ"}
for key in roman_nums:      # キーをすべて取り出す
       print(key, roman_nums[key])

  

関数

●関数の定義

def 関数名(引数1, 引数2, ・・・) : 
     関数ブロック

    return 戻り値

 

●関数の使用

変数 = 関数名(引数1, 引数2, ・・・)

 ※「変数」に関数を実行した結果(戻り値)が代入される

 

●デフォルト引数

関数定義時に引数に値を代入しておく
引数の指定がない場合、自動的にこの値が使用される

def 関数名(引数1=デフォルト値, 引数2=デフォルト値, ・・・) : 
    関数ブロック

   return 戻り値

※デフォルト引数は引数の後ろの方で指定 前半はデフォルト値の指定がない変数

 

●変数の影響範囲

関数内外で同じ名前の変数を定義しても、別のものとして扱われる
関数の中から外で定義した変数は見えるが、関数の外から中で定義した変数は見えない

f:id:masashi_k:20190331203904p:plain

 

高階関数

Pythonでは関数もオブジェクトなので、データとして扱える
 ・関数を変数に代入する
 ・関数をほかの関数に引数として渡す
 ・関数の中で新しい関数を生成して返す
といったことが可能

・「関数をほかの関数に引数として渡す」の例

def execute(func, arg):         # 引数を一つだけ取る関数呼び出しを抽象化
    return func(arg)            # 引数として受け取った関数を実行

print(execute(int, “100”))

 

・「関数の中で新しい関数を生成して返す」の例

def logger(func):
    def inner(*args):         # *args : 引数リスト
        print(“引数:”, args)
        return func(*args)    # 引数として受けた関数を呼び出し
    return inner              # 関数内で定義したinner()を実行

  

メソッド

データに紐づいてデータに対する処理や操作をする関数
クラス内でdefで定義されているもの

データ.メソッド名(引数1, 引数2, …)

※各組み込み型に対して標準で準備されているメソッドもあるし、
 ユーザーで新たなメソッドを定義できる

・リスト型のメソッド 
https://qiita.com/shiren/items/c89e002bc44343b387dc

・文字列型のメソッド
http://motw.mods.jp/Python/str_methods.html

・set型のメソッド
http://python-tech.com/python_used_set/

・ディクショナリ型のメソッド
https://code-graffiti.com/dictionary-in-python/

  

クラス

オブジェクトの設計図のこと
組み込み型に対するオブジェクトとクラスに対するインスタンスは似たような関係

f:id:masashi_k:20190331210210p:plain

●クラスの定義

classの後にクラス名を続けてクラスを定義

f:id:masashi_k:20190331210549p:plain

 例:直方体をクラスで表現

class Prism:
     def __init__(self, width, height, depth):     # 定義時にアトリビュートを自動で作成
     # アトリビュートは.(ドット)を使って定義 もらった引数をアトリビュートに渡す
            self.width = width
            self.height = height
            self.depth = depth
     def content(self):    # メソッドの定義
            return self.width*self.height*self.depth     # 体積を計算して返す

※__init__()は初期化メソッド インスタンス生成時に自動で呼ばれるメソッド
 メソッドには必ず引数としてselfを指定 selfはインスタンス自体を指す

 

●クラスの使用

クラスを関数のように呼び出してインスタンスを生成

例:定義したPrismというクラスを使用

p1 = Prism(10, 20, 30)    # インスタンスの作成 p1がインスタンス
# 定義したメソッドを使用
p1.content()     # 結果:6000

# .(ドット)アトリビュート名で値を取り出せる
p1.height    # 結果:20

f:id:masashi_k:20190331211930p:plain

カプセル化

クラス内で使用するアトリビュートを外から書き換えられないようにすること
クラス内で使用するメソッドを外から使用できないようにすること

「名前の先頭にアンダースコア(_)が1つついたアトリビュートやメソッドは
クラスの内部だけで使用するためにある」というルールがある
  例:_size

より厳しくアトリビュートやメソッドへのアクセスを制限する場合
名前の前にアンダースコアを二つ付ける
  例:__size

 

●クラスの継承

あるクラスを雛形にして別のクラスを作る
 親クラス:スーパークラス
 子クラス:サブクラス

f:id:masashi_k:20190331212707p:plain

●継承のさせ方

class クラス名(スーパークラス名1 [, スーパークラス名2, …]):


例:Prismを継承してCubeというクラスを新たに作る

class Cube(Prism)
       def __init__(self, length):    # 同名のメソッドを定義すると上書きされる
             self.width = self.height = self.depth = length

c = Cube(20)
# スーパークラスで定義したcontentメソッドはそのまま使用可
c.content()     # 結果:8000

 

スーパークラスの取得

super()を使うとスーパークラスを呼び出せる
__init__()をサブクラスで上書きしても元のスーパークラスの関数を使用できる

例:super()関数を使う

class Cube(Prism)
       def __init__(self, length):
             super().__init__(length, length, length)

 

●スロット

アトリビュートの追加を制限
指定した文字列のアトリビュートのみ追加が可能

__slot__ = [‘a’, ‘b’] # a, bというアトリビュートは追加OK
               # それ以外を追加しようとするとエラーになる

 

●プロパティ

データを変更したり、参照する専用のメソッド
  データを設定するメソッド:セッター(setter)
  データを取り出すメソッド:ゲッター(getter)

property([ゲッター [, セッター])

 
例:プロパティの定義、使用

class Prop: def __init__(self): self.__x = 0 # アトリビュートを作る def getx(self): # ゲッター:アトリビュートを返す return self.__x def setx(self, x) # セッター:アトリビュートを書き換え self.__x = x # xというアトリビュートに対して代入や参照を行うとgetx(), setx()というメソッドが呼ばれる x = property(getx, setx) # プロパティを設定 i = Prop() # インスタンスを作る i.x # 結果:0 # アトリビュートxを参照 ゲッターを使用→アトリビュート__xの値を返す i.x = 10 # xに代入 セッターを使用→アトリビュート__xに数値10を代入 i.x # 結果:10 # ゲッターを使用→アトリビュート__xの値を返す

  

モジュール

Pythonではスクリプトファイルをそのままモジュールとして使用できる
.pyの前までがモジュール名

 

●モジュールをインポートするときの挙動
インデントされていない位置に定義されている命令を実行

例: testmodule.py

#!/usr/bin/env python
import sys                        #標準ライブラリをインポート

a = 1                             #変数を定義
b = “some string”

def foo():                        #関数を定義
       print(“This is the function ‘foo’”)

print(“this is the top level”)    #文字列を表示

if __name__ == ‘__main__’:        #ファイル実行時のみ実行される(python testmodule.py)
       print(“this is the code block”)

 

●モジュールインポートの方法

例:「bookmark.py」というファイルにBookmarkクラスを定義した場合

# モジュールのインポート
import bookmark    # bookmark : module

# クラスのインポート
from bookmark import Bookmark    # bookmark : module, Bookmark : class

 

●パッケージ

モジュールとなるファイルを収めたディレクト
(3rd partyのモジュールパッケージもある numpyなど)

 

f:id:masashi_k:20190331215716p:plain

上図のmoduleaをインポートする場合、階層構造をドット(.)で区切って表記

import packagea.modulea

 関数funcaの呼び出しはpackagea.modulea.funca()

または

from packagea import modulea

 関数funcaの呼び出しはmodula.funca()

※パッケージとして使いたいディレクトリには__init__.pyという名前のファイルを置く