🗒️
Python Cheat Sheet
他のプログラミング言語の経験がある方や久々にPythonを使う方向けに、短時間でPythonの言語仕様を思い出すためのCheat Sheetを作成した。
初版ではPythonチュートリアルの内容を中心に記載しているが、今後も内容を追加予定。
制御構文
while文
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a + b
for文
# シーケンス型に対する反復を行う。
# while文とfor文はbreak, continueでの制御が可能。
animals = ['cat', 'dog']
# dictやtupleのリストをfor a, b in xの形式で受け取ることも可能。
for a in animals:
print(a)
# else: 最後のループの後に実行される。
else:
print("end")
if文
if x < 0:
print('negative')
elif x == 0:
print('zero')
else:
print('positive')
match文
# caseに記述したパターンとのマッチングを順に行い、最初にマッチしたパターンを実行する。
# Pythonにswitch文はなく3.10で構造的パターンマッチングが可能なmatchが導入された。
match a:
# | (or) で複数パターンをまとめて記述できる。
case 0 | 1:
print(p)
# シーケンスやオブジェクトに対してunpackと同様の構文で変数に代入できる。
case (x, 1):
print(x)
# ワイルドカードパターン
case _:
raise ValueError("Not a point")
関数定義
# =でデフォルトの引数値を設定できる。
# *args, **kwargs で残りの位置引数、キーワード引数を受け取れる。
def f(x, y=1, *args, **kwargs):
# ドキュメンテーション文字列
# 各セクションの記述方法にはNumpy, Google (下記の記載例)などの流派がある。
"""Do something.
Args:
x: a parameter
...
"""
print(f"x={x}, y={y}, args={args}, kwargs={kwargs}")
# /と*で仮引数を区切ることで引数の指定方法を以下の3種類に制限できる。
# (1) 位置専用、(2) 位置またはキーワード、(3) キーワード専用
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
pass
ラムダ式
def make_incrementor(n):
return lambda x: x + n
デコレータ
import functools
# 引数の関数を実行するラッパー関数を返却する関数を作成する。
def debug(func):
@functools.wraps(func) # __name__等の関数の情報をコピーするためのデコレータ
def wrapper(*args, **kwargs):
print(f"args: {args}, kwargs: {kwargs}")
func(*args, **kwargs)
return wrapper
@debug
def sum(a: int, b: int):
return a + b
データ構造
リスト・タプル
# 内包表記
users = [f"{name}-{i}" for name in ["taro", "hanako"] for i in range(2)]
# 主要なメソッド
users.index('taro-1') # 1
users.pop(1) # taro-1 (要素が削除される)
users.remove("hanako-0")
users.append('jiro-0')
users.sort()
users.reverse()
users.clear() # del users[:] と同じ
# インデックスを使ったループ。enumerateはシーケンス型に対して使える。
for i, u in enumerate(users):
print(f"{i}: {u}")
# タプル
# リストと異なり不変オブジェクト。複数の型を要素に設定されることが多い。
t = (1, "abc") # この場合 () は省略可能。1要素の場合は 1, と記述です。
_, a = t # アンパック
# 重複する要素をもたない、順序づけられていない要素の集まり
s = {1, 2, 3, 1} # {1, 2, 3}
s = set([1, 2, 3, 1]) # set()にシーケンス型を渡して生成もできる。
s = set() # 空のsetを生成する。{}は空のdictを生成することに注意。
d = {'a': 1, 2: 'b'}
# 値の取得
d['c'] = 3 # 存在しないキーの場合KeyErrorとなる。d.get()を使うとNoneとなる。
# 項目の削除
del d['a']
# キー・値でのループ。キーのみの場合はd.keys()、値のみの場合はd.values()と記述できる。
for k, v in d.items():
print(k, v)
モジュール・パッケージ
# パッケージ・モジュールのインポート
# importしたオブジェクトを自モジュールの名前空間に設定する。
# a/ トップレベルパッケージa
# __init__.py パッケージとして認識させるために必要なファイル
# (例外としてnamespace packageではファイルを省略できる。)
# パッケージaの初期化処理を記述する。
# b/ サブパッケージb
# __init__.py パッケージbの初期化処理を記述する。
# c.py モジュールc (func関数が定義されているとする)
import a # a.b.c.func()
from a.b.c import func # func()
from a.b import b as d # d.c.func()
from a import * # b.c.func()
# パッケージaの全て (_で始まるもの以外)の名前をインポートする。
# 名前空間の意図しない変更リスクがあり、推奨されない記述方法。
例外処理
try:
# raiseで例外を発生させる。fromで例外の連鎖を設定できる。
raise ValueError('error') from err
# ValueErrorもしくはその派生クラスを捕捉する。
except ValueError as err:
# except節で例外をraiseすると自動的に元の例外がスタックに追加される。
# 例外の連鎖を無効にするには raise RuntimeError() from None とする。
# https://docs.python.org/3/tutorial/errors.html#exception-chaining
raise RuntimeError()
except Exception as err:
# 例外に対して情報を追加できる。
# https://docs.python.org/ja/3/tutorial/errors.html#enriching-exceptions-with-notes
err.add_note('additional information')
# raiseのみ記述すると同じ例外を再度発生させることができる。
raise
# else: try節で例外が発生しなかった場合に実行される
else:
print("result is", result)
finally:
print("executing finally clause")
# ユーザー定義例外
# https://docs.python.org/3/tutorial/errors.html#user-defined-exceptions
# 典型的にはExceptionもしくはその派生クラスを継承する。
class MyError(Exception):
pass
# ExceptionGroup: 例外をまとめて扱える。通常の例外同様にraise、exceptできる。
# https://docs.python.org/3/tutorial/errors.html#raising-and-handling-multiple-unrelated-exceptions
try:
excs = [OSError(), SystemError()]
raise ExceptionGroup('errors', excs)
# except*でグループ内の例外を絞り込んで捕捉することもできる。
# 要素が絞り込まれたExceptionGroupが渡される。
except* OSError as e:
print(e.exceptions) # (OSError(),)
クラス
# クラス定義
# 参考: https://docs.python.org/3/tutorial/classes.html
class Foo:
# 静的メソッド: 実体は単なる関数。クラスと関連が深い関数をまとめる目的で使う。
# 参考: https://docs.python.org/3/library/functions.html#staticmethod
@staticmethod
def foo(x, y):
pass
# クラスメソッド: 第一引数でクラスが渡される。慣習的に変数名はclsとする。
# ファクトリメソッドの実装が典型的な利用例。
# 参考: https://docs.python.org/3/library/functions.html#classmethod
@classmethod
def bar (cls, x, y):
pass
# クラス変数: クラス定義の直下で宣言する。
x = 1
# コンストラクタ: 第一引数でインスタンスが渡される。慣習的に変数名はselfとする。
def __init__(self, x, y):
# インスタンス変数: private修飾子はなく慣習的に先頭に_を付けて区別する。
self._x = x
# メソッド: 第一引数でインスタンスが渡される。慣習的に変数名はselfとする。
# private修飾子はなく慣習的に先頭に_を付けて区別する。
def baz(self, x, y):
pass
# プロパティ: @property, @{name}.setter, @{name}.deleterデコレータを設定すると、
# 属性として参照 (obj.x)、代入 (obj.x = val)、削除 (del obj.x) ができる。
@property
def y(self):
return self._y
@y.setter
def y(self, y)
self._y = y
# __str__: special methodの1つ。クラスを文字列型にキャストする際に呼び出される。
# その他のspecial method: __getattr__, __iter__, __add__, ...
# https://docs.python.org/3/reference/datamodel.html#special-method-names
def __str__(self):
return f"<Foo(x={self._x})>"
# インスタンス化
f = Foo(1, 2)
# メソッドの呼び出し
f.baz(3, 4)
# 継承: 多重継承は class X(A, B, C, ...) のように記述する。
# 参考: https://docs.python.org/3/tutorial/classes.html#inheritance
class Bar(Foo):
# メソッドのオーバーライド: 親クラスと同名のメソッドを定義するとオーバーライドできる。
# 親クラスのメソッドは `super().{メソッド名}` で呼び出せる。
# 参考: https://docs.python.org/3/library/functions.html#super
def __str__(self):
return f"<Bar(x={self._x})>"
# dataclass: いわゆるrecord型を作る機能。__init__や__repr__が自動的に定義される。
# 参考: https://docs.python.org/3/library/dataclasses.html#module-dataclasses
@dataclass
class Baz:
x: str
y: int = 0 # デフォルト値の設定
イテレータとジェネレータ
# for文でのループはイテレータという仕組みで動作する。
# for c in 'abc' は以下の処理と同じことをする。
it = iter('abc') # 'abc'.__iter__() を呼び出してイテレータオブジェクトを取得する。
next(it) # it.__next__() を呼び出して次の要素を取得する。要素がない場合はStopIteration例外が発生する。
# yield文を使ってiteratorを作成できる。
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index] # この値をnext()で取り出せ、次のnext()呼び出しまで処理が一時中断する。
# Generatorは内包表記で生成することもできる。
g = (i*i for i in range(10))
Discussion