【初心者向け】Python基礎構文解説(関数・例外処理・アンタップ・内包表記・ジェネレータ・デコレータ)

【初心者向け】Python基礎構文解説(関数・例外処理・アンタップ・内包表記・ジェネレータ・デコレータ) プログラミング

この記事では、Pythonの初心者向けに基礎構文について解説していきます。
関数や例外処理、ジェネレータやデコレーターについて解説します。

関数

Pythonの処理を関数で作成することができます。繰り返し共通の処理をする場合や引数によって値を変えたい場合に作成します。
引数には以下のような種類があります。

  • 位置引数:仮引数と引数の設定順番が同じ
  • 可変長位置引数:可変長の仮引数を設定可能、*argsが通例の名称、タプル形式で値を受け取ります。
  • キーワード引数:キーワードで仮引数を設定
  • 可変長キーワード引数:可変長のキーワード引数を設定可能、**kwargsが通例の名称、辞書形式で値を受け取ります。
  • デフォルト値つきの引数:引数はデフォルト値を付けた場合は、それ以降もデフォルト値をつける必要あり
  • キーワード専用引数:引数に*を含めるとそれ以降の仮引数はキーワード引数でなければエラーとなる。
  • 位置専用引数:引数に/を含めるとそれ以前の仮引数は位置引数でないとエラーとなる
# 位置引数
def sum(a, b, c, d, e):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


sum(1, 2, 3, 4, 5)


# 可変長位置引数
def sum(a, b, *args):
    print(f"a = {a}, b = {b}, c = {args[0]}, d = {args[1]}, e = {args[2]}")


sum(1, 2, 3, 4, 5)


# キーワード引数
def sum(a, b, c, d, e):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


sum(1, 2, 3, d=4, e=5)


# 可変長キーワード引数
def sum(a, b, **kwargs):
    print(f"a = {a}, b = {b}, c = {kwargs["c"]}, d = {kwargs["d"]}, e = {kwargs["e"]}")


sum(1, 2, c=3, d=4, e=5)


# デフォルト引数
def sum(a, b, c=0, d=0, e=0):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


sum(1, 2)


# キーワード専用引数
def sum(a, b, c, *, d, e):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


sum(1, 2, 3, d=4, e=5)


# 位置専用引数
def sum(a, b, c, d, e, /):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


sum(1, 2, 3, 4, 5)


# リストでの仮引数
def sum(a, b, c, d, e):
    print(f"a = {a}, b = {b}, c = {c}, d = {d}, e = {e}")


args = [1, 2, 3, 4, 5]
sum(*args)
引数指定の順番

位置引数→可変長位置引数→デフォルト値つき引数→キーワード引数→可変長キーワード引数

例外処理

Pythonの例外処理では、try~execept文を使用します。
通常Pythonで不正な処理が行われた場合エラーが発生しプログラムが終了しますが、try~except文を使用することで正しくエラー処理を行うことができます。
例外処理は以下のような記述になります。

try:
 メインで実行する処理
except:
 メイン処理でエラーが発生した場合に実行する
else:
 メイン処理でエラーが発生しない場合に実行する
Finally:
 エラー有無に関わらず最後に必ず実行する

except as 変数名でエラーを変数に格納することも可能です。
通常、try文内で検証する処理とexecptで検証するエラーは細かく定義することが推奨とされます。
あまり処理が多かったり、エラー条件が多いと何が原因でエラーが発生しているのかわかりにくくなるためです。

例外クラスを自作してraiseで呼び出すことも可能です。

class MyError(Exception):
    title = None
    detail = None


class MyMaxError(MyError):
    title = "Max Error"
    detail = "10以下で入力してください。"


try:
    b = 11
    a = 10 / b
    if b > 10:
        raise MyMaxError
except MyMaxError as e:
    print(e.detail)

try:
    b = 11
    a = 10 / b
except ZeroDivisionError:
    print("0以外を入力してください。")
except TypeError:
    print("数字を入力してください。")
else:
    print(f"処理が成功しました。a = {a}です。")
finally:
    print("処理が終了しました。")


#10以下で入力してください。
#0以外を入力してください。
#処理が終了しました。

アンタップ

リストやタプル内の要素を一つずつの各変数に再代入する処理になります

# リストから変数へ再代入
a, b, c = [1, 2, 3]

# ネストされたものもアンタップ可能
a, b, (c, d, e) = [1, 2, [3, 4, 5]]

# *は、まとめて値を取得できます。(1回だけ使用できます。)
*a, b, c = [1, 2, 3, 4, 5]

内包表記

リストやタプルなどの要素に何かしらの処理をして別のリストなどを作成する場合に、1行で簡易的にコードを記述することができます
ネストした二重、三重リストにも使用でき、後に書いたものが内側のループになります。{集合}、{辞書:辞書}、(ジェネレータ)も内包表記が使用できます。タプルは使用できません。

[変数を使用した処理 for 変数 in イテラブルオブジェクト if 条件式]

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [x * 2 for x in list1 if x > 5]

#[12, 14, 16, 18, 20]

dict1 = [
    {"name": "taro", "age": 15},
    {"name": "hanako", "age": 20},
    {"name": "jiro", "age": 25},
]
dict2 = [k for k in dict1 if k["age"] >= 20]
#[{'name': 'hanako', 'age': 20}, {'name': 'jiro', 'age': 25}]

ジェネレーター

通常のリストやタプルなどは、大量のデータを使用する際にメモリを大量に消費してしまうが、ジェネレータを使用することで、1要素ずつ処理することができます。

# for文
def multiply(*args):
    a = []
    for arg in args:
        a.append(arg * 2)
    return a


b = multiply(1, 2, 3, 4, 5)
# >>>[2, 4, 6, 8, 10]


# generator
def multiply(*args):
    for arg in args:
        yield arg * 2


b = multiply(1, 2, 3, 4, 5)
for c in b:
    print(c)

# >>>
# 2
# 4
# 6
# 8
# 10


# next
def multiply(*args):
    for arg in args:
        yield arg * 2


c = multiply(1, 2, 3, 4, 5)
print(next(c))
print(next(c))

# >>>
# 2
# 4


# generator→list変換
def multiply(*args):
    for arg in args:
        yield arg * 2


c = multiply(1, 2, 3, 4, 5)
d = list(c)
# >>>[2, 4, 6, 8, 10]

デコレーター

共通的な処理を行いたい場合にデコレーターを使用することで簡単に実装できる。デコレーターは引数に関数をとるものなので、特定の関数の前後でログ出力を行いたい場合などでよく使用されます。
@decoratorで処理を行うと、関数側に変更を加えなくても、関数の前後で共通的な処理を行うことが可能となります

def wrapper_func(func):
    def inner_func():
        print("開始します。")
        func()
        print("終了しました。")

    return inner_func


@wrapper_func
def func():
    print(f"こんにちは!!")


func()

# >>>開始します。
# こんにちは!!
# 終了しました。

タイトルとURLをコピーしました