Copy

MIDORIAck ソフトウェア材料の倉庫

Contents ♪

Python3の基本文法
Python3の一通りの基本文法を簡単なコーディング例と共に並べております。
以前に本家サイト(tenkaiken.com)で掲載していたコンテンツですが、ここに移設しました。
2025.04.26
改行・インデント・コメント

改行

インタプリタは改行により入力行の解釈を行う。
一行に文を複数含める場合は「;」で区切る a = 10 + x; b = 100
行末に「\」を置いて文を折り返すことができる s = "あいうえおかきくけこ" \
+ "さしすせそ"
x = a + b * c - d * \
e + f
「()、[]、{}」の中は自由に折り返すことができる s = ("あいうえおかきくけこ"
+ "さしすせそ")
x = (a + b * c - d *
e + f)

インデント

制御構文、関数定義、クラス定義に伴うブロックは、行のインデントの深さで認識される。同じブロックが継続している区間は、行頭のインデントがそろっていなければならない。
if a > 100:
    print(a)        # ブロック開始
    b = a * 10
    print(b)        # ブロック終わり
インデントは空白4文字が基本とされているが、インデントの頭がそろっていれば2文字でもタブ文字でもかまわない。

コメント

「#」以降をインタプリタは解釈しないのでコメントを書くことができる。
複数行を囲むようなコメントの方法はないが、代入のない複数行文字列をコメントのように使う方法がある。
a = 10  # aに10を代入した
# print(a)

'''
複数行文字列をコメントのように使う
a = 10
print(a)
'''
2025.04.26
数値のリテラル
10進数 先頭が0でない数値 12340
2進数 0bからはじまる0か1の数値 0b1011
8進数 0oからはじまる0~7の数値 0o467
16進数 0xからはじまる0~9、A~Fの数値 0x3f9A
10進数の整数は先頭を0にはできない。「05」は5とは解釈されずエラーになる。
16進数の10~15に相当するA~Fは大文字小文字どちらでもよい。
整数の値の範囲は、Python2まではシステムアーキテクチャに準じた32ビットや64ビットの範囲とされていたが、Python3からは無制限になった。次の計算は、オーバーフローにならずに問題なく結果が得られる。
>>> print(123456789**10)
822526259147102579504761143661535547764137892295514168093701699676416207799736601
小数点を含む数値 3.1416
仮数部と指数部で表記 0.031416e+2= 0.031416 ×102
314.16e-2= 314.16 ×10-2
浮動小数点値は、倍精度実数である64ビットの範囲で扱われる。表現可能な仮数は64ビットで表現可能な範囲に制限される。32ビットの単精度実数はない。
2.2250738585072014e-308~1.7976931348623157e+308
2025.04.26
文字列のリテラル
クォーテーションで囲む間を文字列のリテラルと解釈する。
"〜" または'〜'
'ABC'、"あいう" 文字列
"''"、 '""' ダブル/シングルクォーテーションは互いを文字列として解釈する
''、 "" 空文字列
'''UVW
XYZ'''
"""OPQ
RST
UVW"""
複数行の文字列
3つクォーテーションを連続させた区間は、改行を含めることができる
print("ABC"
'DEF')
連続する文字列リテラルは一つの文字列として結合して解釈される。
たとえば、"AAA""BBB"は"AAABBB"として解釈される。
print("UVW\
XYZ")
文字列の行末に「\(バックスラッシュ)」を置いて、次の行から文字列を続けることができる。「\」自身は文字列には含まれない。
インタプリタの内部で処理される文字列データはUnicodeで扱われる。
2025.04.26
エスケープシーケンス
print('ABC\nDEF')
print('GHI\tJKL')
print('ABC\'DEF')
print("\x3f")
print("\u3042")
ABC
DEF
GHI     JKL
ABC'DEF
?

改行やタブ文字のような制御文字は、「\(バックスラッシュ)」に続く1文字との組み合わせによるエスケープシーケンスで表す。
エスケープ文字  
\a ベル
\b バックスペース
\t タブ
\n 改行
\r 復帰(行頭へ移動)
\' '(シングルクォーテーション)
\" "(ダブルクォーテーション)
\\ \(エスケープ文字そのもの)
\035 3桁の0-7の数値からなる8進数が示すコードの文字
\xEB 2桁の0-9A-Fの数値からなる16進数が示すコードの文字
\u1340、\U0001f300 u+4桁またはU+8桁の16進数からなるUnicode文字
2025.04.26
バイト列のリテラル
b'\x00\x02\x1a'、b"\xa8\x90\x03" バイト列
b"\x00\x02\t\n\x0c\xff" 16進数以外のエスケープ文字でもよい
b"abcd$%!\x00" ASCII文字は直接表記できる
先頭に「b」を置いたクォーテーションで囲った区間はバイト列のリテラルとして解釈される。
b'〜' または、b"〜"
1バイト毎のデータはエスケープ文字か、表示可能なASCII文字で表記する。
2025.04.26
ブール値のリテラル
True
False
ブール値(真理値)のリテラルは「True」と「False」である。そのつづり以外、たとえばTRUEやfalseは認められない。
2025.04.26
None
a = None
Noneは「値が無い」ことを表す特殊なデータ型である。変数にNoneを代入することで、「変数は存在するが値が未定」な状態にできる。
2025.04.26
変数の代入
a = 10          # 代入と同時に変数が作られる
a = "ABC"       # 別のものを代入して上書き
b = [1, 2]
変数名 = オブジェクト 
変数宣言は必要ない。変数のデータ型は代入するもので決定する。新しい変数名へデータの代入が行われた時点でその変数が新たに作られ、代入した値で初期化される。
変数の使用可能文字
英字
数字(ただし先頭文字にはできない)
アンダーバー(アンダースコア)
2025.04.26
変数の削除
a = 100
del a
print(a)
NameError: name 'a' is not defined
変数はdel文により削除できる。削除した変数は未定義(存在しない)となる。
2025.04.26
算術演算
a = 7 + 3.2     # 10.2
a = 6.5 - 12    # -5.5
a = -33 + +1    # -32
a = 3 * 1.6     # 4.800000000000001
a = 10 / 3      # 3.3333333333333335
a = 10 // 3     # 3
a = 10 % 3      # 1
a = 2 ** 4      # 16
以下の数値の算術演算子がある。
演算子   演算
+ - 加算・減算(及び各単項演算)
* / 乗算・除算
// 切り捨て除算
% 剰余(モジュロ)
** べき乗
0での徐算はできない。0除算は例外になる。
x = 10 / 0
ZeroDivisionError: division by zero
2025.04.26
浮動小数点値の丸め round()
print(round(2.3456, 2))     # 2.35  
print(round(2.3456))        # 2 
round()関数により浮動小数点値を指定桁で四捨五入できる。桁を省略した場合は整数値に丸められる。
round(浮動小数点, [桁])
2025.04.26
代入演算
a = 10
a += 1
a *= 3
変数の演算とその変数自身への代入は代入演算子でまとめることができる。
例えば「a=a+n」は「a+=n」のようにできる。
  += -= *= /=
代入演算子の種類 **= //= %= &=
  |= ^= <<= >>=
2025.04.26
ビット演算(論理演算)
a = 0b0101
b = 0b1001
x = a & b       # 1
x = a | b       # 1101
x = a ^ b       # 1100
x = ~a          # 1010 = -110 = -6
以下の数値データのビット演算子(論理演算子)がある。
演算子   演算
& 論理積(AND)
| 論理和(OR)
^ 排他的論理和(XOR)
~ 否定(NOT)
否定(not)は2の補数になる。
~x ⇒  -(x + 1)
2025.04.26
ビットシフト
a = 0b0101
x = a >> 1      # 0b10
x = a << 1      # 0b1010
b = 0b1010
x = b >> 1      # 0b101
x = b << 1      # 0b10100
x = b << 16     # 0b10100000000000000000
シフト演算子は数値を2進数としたとき、シフト演算子に続く値のビット数だけ左右にシフトする。
シフト後の最上位または最下位のビットには0が追加される。左シフトでは最上位ビットは消えることなく右に0ビットが付け足される。
>> n nビットシフト
<< n nビットシフト
2025.04.26
文字列・バイト列の連結演算
s = "AB" + 'CD'
print(s)        # ABCD
s += "EF"
print(s)        # ABCDEF
s = "XYZ"
print(s * 3)    # XYZXYZXYZ

b1 = b"\x01\x02"
b2 = b"\x03\x04"
print(b1 + b2)  # b'\x01\x02\x03\x04'
print(b1 * 3)   # b'\x01\x02\x01\x02\x01\x02'
文字列またはバイト列は「+」で連結した文字列/バイト列を作成できる。
「*」で乗算すると、その倍数を繰り返す文字列/バイト列が作成される。
s1 + s2    s1とs2を連結
s * j      sをj回繰り返す
2025.04.26
等価演算・比較演算
a = 10
print(a == 10)  # True
print(a != 20)  # True
print(a > 5)    # True
print(a >= 10)  # True
print(a < 20)   # True
print(a <= 10)  # True
数値の等価、大小を等価演算・比較演算で評価し、結果をブール値で返す。
A==B AとBの値が等しい
A!=B AとBの値が等しくない
A>B、A<B AがBより値が大きい/小さい
A>=B、A<=B AとBの値が等しい、またはAがBより値が大きい/小さい
等価演算は文字列・バイト列・コレクション型の内容が同一かどうかを調べることができる。
集合の比較では、順不同に同じ要素が存在すれば一致と判断される。
辞書の場合は、キーか値のどちらかが異なれば、不一致と判断される。
s = "ABC"
print(s == "ABC")   # True
print(s != "DEF")   # True

b1 = b"/x01/x02/x03/x04"
b2 = b"/x01/x02/x03/x04"
print(b1 == b2)             # True
b3 = b"/x01/x22/x03/x04"
print(b1 == b3)             # False

tp = (10, 20)
print(tp == (10, 20))       # True
lst = [10, 20]
print(lst == [10, 20])      # True
se = {10, 20}
print(se == {20, 10})       # True
dic = {"a": 10, "b": 20}
print(dic == {"a": 10, "b": 20})    # True
print(dic == {"a": 10, "c": 20})    # False
print(dic == {"a": 10, "b": 30})    # False
2025.04.26
オブジェクトの等価演算 is/is not
a = [1, 2, 3]
b = a
print(a is b)       # True
print(a is not b)   # False
c = a.copy()
print(a == c)       # True
print(a is c)       # False
x = None
print(x is None)    # True
値ではなく、オブジェクトの参照元が同じかどうかをis、is not演算子で評価し、ブール値で返す。
コピーを代入した変数とコピー元との間では、「==」で比較すると値が一致するのでTrueだが、isの評価では、コピーにより互いに別々のオブジェクトを持つためFalseになる。
Noneは常に唯一のNoneオブジェクトを参照するので、isの評価は常にTrue。
2025.04.26
真偽の論理演算
a = 3
b = 8
print(a > 10 or a < 5)      # True
print(a < 10 and b >= 5)    # True
a = None
print(not a)                # True
関係演算での評価や式の評価結果を、論理演算で評価し、ブール値で返す。
A and B AかつB(AND)
A or B AまたはB(OR)
not A Aでない(NOT)
2025.04.26
演算の優先
演算子の優先順位は以下のようになっている。
同列内では左がより高い。
最も高い ** べき乗
~ 否定(補数)
-a, +a 単項演算
%, *, /, // 剰余、乗算、除算、切り捨て除算
+, - 加算、減算
<<, >> ビットシフト
&, ^, | ビット論理積、排他的論理和、論理和
>, >=, <, <= 比較演算
==, != 等価演算
in, not in 所属、非所属
is, is not オブジェクトの同一、非同一
not 論理否定
and, or 論理積、論理和
最も低い lambda ラムダ
数学と同様に( )で囲んだ中の式が演算子の優先順位に関係なく先に演算される。また( )が式に複数ある場合は、左の項から演算される。
a = 4
b = (a + 2) * 10
print(b)

if (a > 3) and (b > 30):
    print(a)
60
4
2025.04.26
データ型取得・データ型比較 type() is
a = 10
print(type(a))      # <class 'int'>
a = "ABC"
print(type(a))      # <class 'str'>
a = [1, 2]
print(type(a))      # <class 'list'>
def Fun():
    pass
print(type(Fun))    # <class 'function'>
全てのデータは内部的に各データ型のクラスで定義されている。
type()関数にデータを与えると、そのデータ型(クラス)が取得できる。
データ型 = type(オブジェクト)
以下は主なプリミティブなデータ型のクラス名である。
int(整数) float(浮動小数点) str(文字列)
bool(ブール) list(リスト) tuple(タプル)
dict(辞書) tuple(タプル) set(セット)
function(関数)

データ型の判定

a = 100
print(type(a) is int)       # True
a = "ABC"
print(type(a) is str)       # True
print(type(a) is not float) # True
print(type(a) == str)       # True
type()で取得したデータ型を「is(not is)」、あるいは比較演算子で一致(不一致)判定ができる。
type(オブジェクト) is データ型名
type(オブジェクト) not is データ型名
type(オブジェクト) == データ型名
type(オブジェクト) != データ型名
2025.04.26
暗黙の数値間変換
a = 4 * 2.4             # 9.6
a = True + 2            # 3
a = 5.0 - False         # 5.0
異なる数値型の演算では、自動的(暗黙)に適切なデータ型の変換が行われる。
整数と浮動小数点が同じ式に混在する場合は、整数は自動的に浮動小数点に変換してから演算される。
4 * 2.4         4を4.0に変換してから演算
ブール値が数値と共に演算する場合は、Trueは1、Falseは0に変換される。
True + 2        Trueが1に変換

5.0 - False     Falseが0.0に変換
2025.04.26
数値の明示的型変換(キャスト)
a = int(12.3)           # 12
a = int(1.72e2)         # 172
a = int('456')          # 456
a = int(True)           # 1
a = int(False)          # 0

a = float(12)           # 12.0
a = float('34.5')       # 34.5
a = float('2.5e3')      # 2500.0
a = float(True)         # 1.0
a = float(False)        # 0.0

a = int('2.34e3')       # エラー
a = int('0xba')         # エラー
データ型(x)のようにすると、xのそのデータ型(クラス)への変換を試みる。
例えばint(x)は、xを可能な限り整数に変換して返す。
変換できないオブジェクトが指定された場合はエラー(ValueError例外)となる。
データ型(x)     データ型への変換
2025.04.26
文字列への変換 str()
print(str(123))         # 123
print(str(34.5))        # 34.5
print(str(True))        # True
print(str(False))       # False
print(str([77, 88]))    # [77, 88]
print(str(None))        # None
str(x)は、xの文字列への変換を可能な限り試みる。
リストなどのコレクションも含めて、あらゆるオブジェクトの文字列変換を試みる。
2025.04.26
バイト列と数値の変換 to_bytes()
n = 32767
print(n.to_bytes(2, "big"))     # b'\x7f\xff'
print(n.to_bytes(2, "little"))  # b'\xff\x7f'
print(n.to_bytes(4, "little"))  # b'\xff\x7f\x00\x00'

a = int.from_bytes(b"\x7f\xff", "big")      # a = 32767
a = int.from_bytes(b"\xff\x7f", "little")   # a = 32767
整数値は次のようにバイト列へ変換、あるいはバイト列から整数へ変換できる。
バイトオーダーには、ビッグエンディアンは「big」、リトルエンディアンは「little」を指定する。
バイト列 = 整数.to_bytes(バイト数, バイトオーダー)
整数値 = int.from_bytes(バイト列, バイトオーダー)
2025.04.26
文字列とバイト列の変換 encode() decode()
s = "あいう"
print(s.encode())           # b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
print(s.encode("utf-8"))    # b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
print(s.encode("cp932"))    # b'\x82\xa0\x82\xa2\x82\xa4'
s = "ABCD\a"
print(s.encode("ascii"))    # b'ABCD\x07'

bi = b"\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86"
print(bi.decode())          # あいう
bi = b"\x31\x32\x33"
print(bi.decode("ascii"))   # 123
print(str(bi, "utf-8"))     # あいう

print(b"\xa1\xa2\xa3\xaf".hex())    # a1a2a3af
文字列は、encode()メソッドにより任意の文字コードのバイト列に変換できる。
文字コードを省略した場合は、デフォルトとしてUTF-8が適用される。
バイト列 = 文字列.encode(文字コード)
バイト列は、decode()メソッドにより文字列に変換できる。
指定する文字コードで文字列を解釈する。省略時はUTF-8が適用される。
文字列 = バイト列.decode(文字コード)
あるいはstr()にバイト列と文字コードを指定すると、バイト列を文字列に変換できる。
文字列 = str(バイト列, 文字コード)
バイト列は、hex()メソッドにより16進数を表す文字列に変換できる。1バイトを2桁の16進数で表現する。
16進数の文字列 = バイト列.hex()
2025.04.26
文字列を区切り文字で分割 split()
s = "ABC DEF GHI"
sl = s.split()          # ['ABC', 'DEF', 'GHI']
s = "ABC/DEF/GHI"
sl = s.split('/')       # ['ABC', 'DEF', 'GHI']
s = "A B C,D E F,G H I"
sl = s.split(',')       # ['A B C', 'D E F', 'G H I']

s = "ABC\nDEF\nGHI"
sl = s.splitlines()     # ['ABC', 'DEF', 'GHI']
文字列には、文字列を加工するメソッドが用意されている。
split()メソッドは、文字列を指定する区切り文字で分割してリストを返す。
区切り文字を省略すると、デフォルトで空白文字が適用される。
リスト = 文字列.split(区切り文字)
またsplitlines()メソッドは、改行文字を含む文字列を、行ごとに区切ってリスト化する。
リスト = 文字列.splitlines()
2025.04.26
文字列を中央・左寄せ・右寄せ center()
w = "ABC"
print(f"[{w.center(7)}]")   # [  ABC  ]
print(f"[{w.ljust(7)}]")    # [ABC    ]
print(f"[{w.rjust(7)}]")    # [    ABC]
center()、ljust()、rjust()メソッドは半角桁数幅のスペースの中に、文字列をセンタリング・左寄せ・右寄せに配置した文字列を返す。
文字列.center(半角桁数) センタリング
文字列.ljust(半角桁数) 左寄せ
文字列.rjust(半角桁数) 右寄せ
2025.04.26
文字列を大文字・小文字変換 upper() lower()
s = "abcDEF"
print(s.upper())            # ABCDEF
print(s.lower())            # abcdef
print(s.swapcase())         # ABCdef
upper()、lower()、swapcase()メソッドは、英字の大文字と小文字を変換する。
文字列.upper() 大文字に変換
文字列.lower() 小文字に変換
文字列.swapcase() 大文字と小文字を交換
2025.04.26
文字列の前後の文字を除去 stlip()
s = "  ABC  "
print(f"[{s.strip()}]")     # [ABC]
print(f"[{s.lstrip()}]")    # [ABC  ]
print(f"[{s.rstrip()}]")    # [  ABC]
s = "123ABC456"
print(f"[{s.strip('123456')}]") # [ABC]
strip()メソッドは、引数に指定する文字列に含まれる文字を、文字列の先頭と末尾から除去する。
引数を省略するとデフォルトで空白・タブが除去される。また、lstrip()は先頭のみ、rstrip()はメソッド末尾のみを除去する。
文字列.strip(除去文字からなる文字列) 先頭と末尾から文字を除去する
文字列.lstrip(除去文字からなる文字列) 先頭の文字を除去する
文字列.rstrip(除去文字からなる文字列) 末尾の文字を除去する
2025.04.26
文字の種類を判定 is〜()
print("XyZ".isalpha())          # True
print("12AB".isalnum())         # True
print("ABC".isupper())          # True
print("abc".islower())          # True
print("123".isdigit())          # True
print("\t \n".isspace())        # True
print("abcあいう".isascii())    # False
is〜から始まるメソッドにより、文字列に含まれる文字の種類を判定する。
isalpha() 文字列がすべて英字ならTrue
isalnum() 文字列がすべて英数字ならTrue
isupper() 文字列がすべて大文字ならTrue
islower() 文字列がすべて小文字ならTrue
isdigit() 文字列がすべて数字ならTrue
isspace() 文字列がすべて改行か空白ならTrue
isascii() 文字列がすべて半角文字(ASCII文字)ならTrue
2025.04.26
文字の一致検索 find()
s = "ABCDEFGABCDEFG"
i = s.find("DEF")       # 3
i = s.rfind("BCD")      # 8
c = s.count("DEF")      # 2
文字列のfind()メソッドは、文字列の中から指定の文字列パターンに最初に一致した位置(先頭は0)を返す。
rfind()メソッドは文字列の後方から検索して最初に一致した位置を返す。
count()メソッドは、文字列パターンが一致した回数を返す。
最初に一致した位置 = 文字列.find(文字列パターン)
後ろから一致した位置 = 文字列.rfind(文字列パターン)
パターン一致した回数 = 文字列.count(文字列パターン)
2025.04.26
文字の先頭と末尾の部分一致 startswith()
s = "ABCDEFG"
s.startswith("ABC")         # True
s.startswith("ABC", 0, 5)   # True
s.startswith("ABC", 0, 2)   # False
s.startswith("BCD", 1)      # True

s.endswith("EFG")           # True
s.endswith("EFG", 4, 7)     # True
s.endswith("EFG", 4, 6)     # False
s.endswith("FG", 5)         # True
文字列のstartswith()メソッドは文字列の先頭から、endswith()メソッドは末尾からの部分一致を調べる。
文字列中の一致を調べる範囲を引数で指定できる。一致範囲は、開始で指定する位置から停止で指定する位置のひとつ手前までになる。例えば開始を0、停止を3に指定した場合は、一致を調べる範囲は0〜2となる。開始と停止を省略した場合は、それぞれ文字列の先頭と末尾位置が適用される。
True|False = 文字列.startswith(文字列パターン, 開始, 停止)
True|False = 文字列.endswith(文字列パターン, 開始, 停止)
2025.04.26
文字列を別の文字列に置換 replace()
s = "ABCDEFGABCDEFG"
r = s.replace("DEF", "(DEF)")       # ABC(DEF)GABC(DEF)G
r = s.replace("DEF", "(DEF)", 1)    # ABC(DEF)GABCDEFG
文字列のreplace()メソッドは、文字列中の文字列パターンに一致する箇所を、指定する文字列に置き換える。
先頭からの置換する回数を指定できる。置換後の文字列を新たに生成して返す。元の文字列は変更しない。
置換後文字列 = 文字列.replace(文字列パターン, 置換文字列, 回数)
2025.04.26
文字列のフォーマット f{..}
print("s={} i={} f={}".format("ABC", 100, 1.23))
# s=ABC i=100 f=1.23

a = 100
b = "ABC"
c = 1.23
print("s={1} i={0} s={1} f={2:.3f}".format(a, b, c))
# s=ABC i=100 s=ABC f=1.230

print(f"s={b} i={a} f={c:.3f}")
# s=ABC i=100 f=1.230
文字列のformat()メソッドは、文字列中の{}の部分に、format()に与える引数を対応させて出力できる。{}には書式を指定できる。
{n}         format()の引数の位置を指定 先頭は0とする。
{n:書式}    「:」に続き表示の書式を指定
あるいはformat()メソッドを使わずに、文字列リテラルの前に「f」をつけた f"~"、f'~'の中に{変数}のように直接表示したいデータを埋め込む方法がある。
f"... {変数} ..."
f'... {変数:書式} ...'
書式の指定方法は以下の通り。
{:8} 255      8桁で左寄せ
{:<8} ABC      8桁で左寄せ
{:^8}   255    8桁で中央せ
{:>8}      ABC 8桁で右寄せ
{:08} 00000255 8桁で0で埋める
{:b} 11111111 2進数
{:o} 377 8進数
{:x} ff 16進数
{:.2} 0.12 小数点以下2桁
{:.6f} 0.123400 小数点以下6桁
{:.6e} 1.2340e-01 浮動小数点を指数で表記
{:.0%} 12% パーセントで表記
2025.04.26
バイト列の生成 bytes()
print(bytes(5))             # b'\x00\x00\x00\x00\x00'
print([1, 8, 15, 128, 23])  # b'\x01\x08\x0f\x80\x17'
print(bytes(range(1, 5)))   # b'\x01\x02\x03\x04'
バイト列は1バイト単位でバイナリデータを格納する配列データである。
byte()に整数値を与えると、その数の0からなるバイト列が生成される。1バイト整数値からなるリスト、タプルを指定すると、数値の列からなるバイト列が生成される。また、range()が返す反復可能(イテラブル)な配列を指定すると、その数値列からなるバイト列が生成される。
バイト列 = bytes(整数値)
バイト列 = bytes(数値リスト)

変更可能なバイト列の生成

lst = [1, 2, 3, 4, 5]
barr = bytearray(lst)
barr[ 2 ] = 0xbb
print(barr)         # bytearray(b'\x01\x02\xbb\x04\x05')
byte()が生成するバイト列は変更できない。それに対し、bytearray()は変更可能なバイト列を生成する。
ただし、bytearray()で生成したバイト列はbytearrayクラスのオブジェクトであり、byte()で生成されるバイト列とは別物である。
2025.04.26
リストの生成 list()
lst = []                    # 空のリスト
lst = list()                # 空のリスト
lst = [10, 20, 30, 40]
lst = ["AB", "CD", "EF"]
lst = [10, "AB", 20, "CD"]  # 異なるデータ型のリスト
lst = [a, 200, b, 400]      # 変数のリスト
リストは、複数のオブジェクトを順序付けて格納するコレクションである。リストは要素の追加・削除など変更が可能である。
リストは、[]の中に要素をカンマ「,」で区切って並べる。
[要素, 要素, ...]
リテラルのみならず、変数や演算式、関数、リストやタプルなどのコレクションを要素にできる。
2025.04.26
配列からのリストの生成
lst = list("ABC")                   # 文字列から
print(lst)                          # ['A', 'B', 'C']
lst = list(b"\x01\x02")             # バイト列から
print(lst)                          # [1, 2] 
lst = list("ABC", 123, "DEF")       # タプルから
print(lst)                          # ['ABC', 123, 'DEF']
lst = list({1:"A", 2:"B"})          # 辞書から
print(lst)                          # [1, 2]
lst = list({"A", "B"})              # セットから
print(lst)                          # ['A', 'B']
lst = list(range(1, 3))             # range()から
print(lst)                          # [1, 2]
list(x)は、xのリストへの変換を試みる。反復可能(イテラブル)な配列型のオブジェクトはリストに変換できる。
リスト = list(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのリストになる。辞書からの場合は、キーのみからなるリストになる。
2025.04.26
リストのアンパック
lst = ["ABC", 100, "XYZ"]
a, n, x = lst
print(a, n, x)      # ABC 100 XYZ
リストの要素を分解(アンパック)して要素に対応する変数に一括で代入できる。
変数0, 変数1, ... , 変数n = [要素0, 要素1, ... , 要素n]
代入される変数の列は変数からなるタプルなので、リストからタプルへの要素ごとの変数の代入になる。
2025.04.26
リストの連結
lst = ["ABC", "DEF"] + [100, 200, 300]
print(lst)      # ['ABC', 'DEF', 100, 200, 300]
リスト同士を「+」で連結してリストを作成できる。
リスト = リスト1 + リスト2
2025.04.26
リストの拡張 extend()
lst = ["ABC", 100]
lst.extend(["DEF", 200])
print(lst)      # ['ABC', 100, 'DEF', 200]

lst = ["ABC", 100]
lst += ["DEF", 200]
print(lst)      # ['ABC', 100, 'DEF', 200]
リストのextend()メソッドは、リストに別のリストを末尾に追加して拡張する。
リストを代入演算の「+=」で別のリストを連結しても同様なことができる。「+」で連結する場合は、連結したリストを新たに生成するが、extend()の場合はそのリストが拡張する。
リスト1.extend(リスト2)
リスト1 += リスト2
元のリスト1にリスト2が追加されて拡張する。リスト2はそのまま残る。
2025.04.26
リストへ要素を追加・挿入・削除

追加

lst = ["ABC", "DEF"]
lst.append("GHI")
print(lst)      # ['ABC', 'DEF', 'GHI']
リストのappend()メソッドは、リストの末尾に要素を1つ追加する。
リスト.append(要素)

挿入

lst = ["ABC", "DEF", "JKL"]
lst.insert(2, "GHI")
print(lst)      # ['ABC', 'DEF', 'GHI', 'JKL']
リストのinsert()メソッドは、リストに要素を1つ挿入する。
指定する位置(添字)に挿入する。0の場合は先頭への挿入になる。
リスト.insert(位置, 要素)

削除

lst = ["ABC", "DEF", "GHI"]
lst.remove("DEF")
print(lst)      # ['ABC', 'GHI']

lst = ["ABC", "DEF", "GHI"]
del lst[1:3]
print(lst)      # ['ABC']
リストのremove()メソッドは、引数で指定する要素をリストから削除する。
同じ要素が複数存在する場合は、先頭から一致する要素が削除される。
リスト.remove(要素)
del文によりリストの位置(添字)を指定して削除できる。位置はスライスで範囲を指定できる。
del リスト[位置]
2025.04.26
リストから要素を取り出し pop()
lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.pop())        # JKL
print(lst)              # ['ABC', 'DEF', 'GHI']

lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.pop(1))       # DEF
print(lst)              # ['ABC', 'GHI', 'JKL']
リストのpop()メソッドは、リストから要素を取り出す。
取り出した要素を返し、リストから削除する。取り出す位置の指定がない場合は末尾からである。
取り出した要素 = リスト.pop()
取り出した要素 = リスト.pop(位置)
2025.04.26
リストから要素を検索 index()
lst = ["ABC", "DEF", "GHI", "JKL"]
print(lst.index("GHI"))     # 2
print(lst.index("XYZ"))     # ValueError
リストのindex()メソッドは、指定する要素が存在するリスト中の位置(添字)を返す。
指定する値の要素が存在しない場合はエラー(ValueError例外)になる。
位置 = リスト.index(要素)
2025.04.26
リストから要素の数を取得 count()
lst = [5, 4, 9, 1, 3, 5, 6, 3, 5, 8]
print(lst.count(3))     # 2
print(lst.count(5))     # 3
print(lst.count(7))     # 0
リストのcount()メソッドは、指定する要素が含まれている数(回数)を返す。
存在する数 = リスト.count(要素)
2025.04.26
タプルの生成 tuple()
tp = ()                     # 空のタプル
tp = tuple()                # 空のタプル
tp = (10, 20, 30, 40)
tp = ("AB", "CD", "EF")
tp = (10, "AB", 20, "CD")   # 異なるデータ型のタプル
tp = (a, 200, b, 400)       # 変数のタプル
tp = 100, 200, 300          # ()はなくてもよい
tp = ("ABC",)               # 要素が1つのタプル
タプルは、複数のオブジェクトを順序付けて格納するコレクションである。タプルはリストとは異なり、要素の追加・削除など生成以降は変更できない。
タプルは、要素をカンマ「,」で区切って並べる。多くの場合、タプルの範囲をわかりやすくするために()で囲む。
空のタプルを生成しても要素を入れることはできない。
(要素, 要素, ...)
要素が1つのタプルの生成は「,」を末尾に付けることで、それが単一データではなくタプルであることをインタプリタに解釈させる必要がある。
リテラルのみならず、変数や演算式、関数、コレクションなどを要素にできる。
2025.04.26
配列からのタプルの生成
tp = tuple("ABC")                   # 文字列から
print(tp)                           # ('A', 'B', 'C')
tp = tuple(b"\x01\x02")             # バイト列から
print(tp)                           # (1, 2)
tp = tuple(["ABC", 123, "DEF"])     # リストから
print(tp)                           # ('ABC', 123, 'DEF')
tp = tuple({1:"A", 2:"B"})          # 辞書から
print(tp)                           # (1, 2)
tp = tuple({"A", "B"})              # セットから
print(tp)                           # 'A', 'B'
tp = tuple(range(1, 3))             # range()から
print(tp)                           # 1, 2
tuple(x)は、xのタプルへの変換を試みる。
反復可能(イテラブル)な配列型のオブジェクトはタプルに変換できる。
タプル = tuple(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのタプルになる。辞書からの場合は、キーのみからなるタプルになる。
2025.04.26
タプルのアンパック
tp = ("ABC", 100, "XYZ")
a, n, x = tp
print(a, n, x)      # ABC 100 XYZ
タプルの要素を分解(アンパック)して要素に対応する変数に一括で代入できる。
変数0, 変数1, ... , 変数n = (要素0, 要素1, ... , 要素n)
この場合、変数の列からなるタプルへの対応するタプルの代入になる。
2025.04.26
タプルの連結
tp = ("ABC", "DEF") + (100, 200, 300)
print(tp)       # ('ABC', 'DEF', 100, 200, 300)
タプル同士を「+」で連結したタプルを作成できる。
タプル = タプル1 + タプル2
2025.04.26
タプルから要素を検索 index()
タプルのindex()は、指定する要素が存在するタプル中の位置(添字)を返す。
指定する値の要素が存在しない場合はエラー(ValueError例外)になる。
tp = ("ABC", "DEF", "GHI", "JKL")
print(tp.index("GHI"))      # 2
print(tp.index("XYZ"))      # ValueError
位置 = タプル.index(要素)
2025.04.26
タプルから要素の数を取得 count()
tp = (5, 4, 9, 1, 3, 5, 6, 3, 5, 8)
print(tp.count(3))      # 2
print(tp.count(5))      # 3
print(tp.count(7))      # 0
タプルのcount()メソッドは、指定する要素が含まれている数(回数)を返す。
存在する数 = タプル.count(要素)
2025.04.26
辞書の生成 dict()
dic = {}                    # 空の辞書
dic = dict()                # 空の辞書
dic = {"AB": 10, "CD": 20, "EF": 30}
dic = {1: "ABC", 2: "DEF", 3: "GHI"}
dic = {(1, 10): "ABC", (2, 20): "DEF"}
dic = {10: "ABC", "X": (1, 2)}      # 型が統一していなくてもよい
dic = dict(a = 10, b = 20, c = 30)  # 代入式から辞書を生成
辞書は、キーに対応する値の組を集めるコレクションである。辞書の要素の順番は意味を持たない。
辞書は、{}の中に「キー:値」の組み合わせを「,」で区切って並べる。
辞書は要素の追加・削除など変更が可能である。
{キー:値, キー:値, ...}
dict()の引数に変数と値の代入式を列挙することで、それらの変数をキーとした辞書を生成できる。
辞書 = dict(変数=値, 変数=値, ...)
変更不可(イミュータブル)なオブジェクトをキーにできる。
キーと値は、リテラルのみならず、変数や演算式、関数、コレクションなどを設定できる。辞書内で同じ値は重複できるが、キーは重複できない。
2025.04.26
リスト・タプルからの辞書の生成
dic = dict( [("ABC", 100), ("DEF", 200), ("GHI", 300)] )
print(dic)      # {'ABC': 100, 'DEF': 200, 'GHI': 300}

dic = dict( (["ABC", 100], ["DEF", 200], ["GHI", 300]) )
print(dic)      # {'ABC': 100, 'DEF': 200, 'GHI': 300}
dict()に、キーと値の組のリスト(タプル)からなるリスト(タプル)を与えると、辞書に変換して生成する。
辞書は要素の順番に意味を持たないので、変換元のリストやタプルの順に辞書が整列されるとは限らない。
{キー:値, キー:値, ...} = dict([(キー, 値), (キー, 値), ... ])
{キー:値, キー:値, ...} = dict(([キー, 値], [キー, 値], ... ))
2025.04.26
キーを辞書に追加・要素を削除

キーを追加

dic = {"a": 10, "b": 20, "d": 40}
dic["c"] = 30   # 追加
print(dic)      # {'a': 10, 'b': 20, 'd': 40, 'c': 30}
dic["c"] = 300  # 変更
print(dic)      # {'a': 10, 'b': 20, 'd': 40, 'c': 300}
辞書に存在しないキーを指定して代入を行うと、そのキーと代入した値が辞書に追加される。
辞書[新規キー] = 値
既に存在するキーを指定して代入を行うと、値が上書き変更される。

要素を削除

dic = {"x": 10, "y": 20, "z": 30}
del dic["y"]
print(dic)      # {'x': 10, 'z': 30}
del文により辞書のキーを指定すると、その要素を削除できる。
del 辞書[キー]
2025.04.26
辞書の拡張 update()
dic1 = {"a": 10, "b": 20}
dic2 = {"x": 100, "y": 200}
dic1.update(dic2)
print(dic1)     # {'a': 10, 'b': 20, 'x': 100, 'y': 200,}
辞書のupdate()メソッドは、辞書に別の辞書を取り込んで拡張する。
辞書1.update(辞書2)
元の辞書1に辞書2が追加されて拡張する。辞書2はそのまま残る。
2025.04.26
セットの生成 set()
se = set()                  # 空のセット
se = {5, 8, 2, 9}
se = {10, "ABC", 2.5}       # 異なるデータ型のセット
se = {a, "ABC", b, "DEF"}   # 変数のセット 
se = {"ABC"}                # 要素が1つのセット
セット(集合)は、オブジェクトの集合として扱うことができるコレクションである。セットの要素の順番は意味を持たない。
セット(集合)は、{}の中に要素をカンマ「,」で区切って並べる。セットは要素の追加・削除など変更が可能である。
空のセットはset()で生成する。{}では辞書の生成になるのでセットの生成はできない。
{値, 値, ...}
2025.04.26
配列からのセットの生成
se = set("ABC")                     # 文字列から
print(se)                           # {'C', 'A', 'B'}
se = set(b"\x01\x02")               # バイト列から
print(se)                           # {1, 2}
se = set([10, 20, 30, 40])          # リストから
print(se)                           # {40, 10, 20, 30}
se = set(("ABC", "DEF", "GHI"))     # タプルから 
print(se)                           # {'GHI', 'DEF', 'ABC'}
se = set({1:"A", 2:"B"})            # 辞書から 
print(se)                           # {1, 2}
se = set(range(1, 3))               # range()から
print(se)                           # {1, 2}
set(x)は、xのセットへの変換を試みる。
反復可能(イテラブル)な配列型のオブジェクトはセットに変換できる。セットは、要素の順番に意味がないので、リストやタプルの順にセットの要素が整列されるとは限らない。
セット = set(配列オブジェクト)
文字列・バイト列は、1文字・1バイトのセットになる。
辞書からの場合は、キーのみからなるセットになる。
2025.04.26
セットへ要素を追加・削除

追加

se = {4, 9, 3, 8}
se.add(5)
print(se)       # {3, 4, 5, 8, 9}
セットのadd()メソッドは、セットに要素を追加する。
セット.add(要素)

削除

se = {8, 7, 3, 6}
se.remove(3)
print(se)       # {8, 6, 7}
セットのremove()メソッドは、引数で指定する要素をセットから削除する。
セット.remove(要素)
2025.04.26
セットの集合演算
se1 = {"A", "B", "C", "D"}
se2 = {"C", "D", "E", "F"}
print(se1 & se2)        # {'C', 'D'}
print(se1 | se2)        # {'A', 'D', 'F', 'B', 'E', 'C'}
print(se1 - se2)        # {'A', 'B'}
print(se1 ^ se2)        # {'E', 'A', 'F', 'B'}

se1 = {5, 3, 8, 2, 7}
se2 = {3, 7}
print(se2 <= se1)       # True
print(se2 < se1)        # True
print(se1 < se1)        # False
セットは集合同士の集合演算ができる。また比較演算子により、一方のセットが他方の部分集合かどうかを判定できる。
集合1 & 集合2 積集合 両方に共通する部分
集合1 | 集合2 和集合 両方を合わせた集合
集合1 - 集合2 差集合 集合1から集合2に存在するものを除く
集合1 ^ 集合2 対称差集合 両方に共通する部分以外
集合1 <= 集合2 部分集合の判定 集合1は集合2に含まれる、または同一
集合1 < 集合2 真部分集合の判定 集合1は集合2に含まれる、同一を除く
2025.04.26
添字による配列の参照
s = "あいうえ"
print(s[2])                 # 'あ'
print(s[-1])                # 'え'

bi = b"\x01\x02\x03\x04"
print(bi[2])                # 3

ba = bytearray(bi)
ba[2] = 0xcc                # 配列の変更
print(ba)                   # bytearray(b'\x01\x02\xcc\x04')

lst = ["ABC", "DEF", "GHI"]
print(lst[1])               # DEF
lst[1] = "def"
print(lst[1])               # ["ABC", "def", "GHI"]

tp = (10, 20, 30)
print(tp[2])                # 30
tp = ([10, "A"], [20, "B"], [30, "C"])
print(tp[2][1])             # C
文字列、バイト列、リスト、タプルおよび反復可能(イテラブル)で配列のように整列しているオブジェクトは、整数の位置(添字/索引番号)で個別要素(文字・バイト)を参照できる。
添字は整数であれば、変数や式の結果、関数の戻り値でもかまわない。先頭要素は0である。「-1」とすると末尾の参照になる。
文字列[n]
バイト列[n]
リスト[n]
タプル[n]
リストとbytearray型は変更可能なので、参照した要素を上書きで代入できる。
リスト[n] = 値
配列オブジェクトが多次元の場合は、次元数だけ[]の参照を繰り返す。右の方ほど深い次元(入れ子の奥)の参照になる。
配列[n][m][...
2025.04.26
スライス
lst = [10, 20, 30, 40, 50, 60, 70]
print(lst[0:4])             # [10, 20, 30, 40]
print(lst[3:])              # [40, 50, 60, 70]
print(lst[:3])              # [10, 20, 30]
print(lst[::2])             # [10, 30, 50, 70]
print(lst[2:6:2])           # [30, 50]
print(lst[2::2])            # [30, 50, 70]
print(lst[::-1])            # [70, 60, 50, 40, 30, 20, 10]
print(lst[:-1])             # [10, 20, 30, 40, 50, 60]
print(lst[-1])              # [70]
print(lst[::])              # [10, 20, 30, 40, 50, 60, 70] コピー
lst[2:4] = [300, 400]       # 区間へ代入
print(lst)                  # [10, 20, 300, 400, 50, 60, 70]
sta = 1
end = 4
print(lst[sta:end + 1])     # [20, 30, 40, 50] 変数で指定

tp = (10, 20, 30, 40, 50, 60, 70)
print(tp[2:6:2])            # (30, 50)

s = "あいうABC"
print(s[0:3])               # 'あいう'
bi = b"\x01\x02\xa0\xb0"
print(s[2:4])               # b'\xa0\xb0'
ba = bytearray(bi)
ba[1:3] = bytearray(b"\x22\xaa")
print(ba)                   # bytearray(b'\x01"\xaa\xb0')
文字列、バイト列、リスト、タプルおよび反復可能(イテラブル)で配列のように整列しているオブジェクトは、スライスにより部分配列を参照できる。
開始添字から停止添字の手前までの範囲を、間隔のステップ数で参照する。それらは整数であれば、変数や式の結果、関数の戻り値でもかまわない。
開始と停止の添字の先頭は0からで、-1で末尾を指定できる。間隔が負数の場合は、停止から開始の方向へ逆順になる。
配列[開始添字:停止添字:間隔]
添字と間隔は省略でき、省略時は次のように適用される。
開始省略 0
停止省略 末尾
間隔省略 1
スライスの参照で返る部分配列は、その配列型で新たに生成される。
リストとbytearray型は変更可能なので、スライスで参照した部分リストへの代入で変更ができる。
2025.04.26
文字列・バイト列・コレクションの長さ len()
s = "ABCDEFG"
print(len(s))               # 7
s = "あいうえお"
print(len(s))               # 5
bi = b"\x01\x02\x03\x04"
print(len(bi))              # 4
lst = [10, 20, 30, 40]
print(len(lst))             # 4
tp = (10, 20, 30, 40)
print(len(tp))              # 4
dic = {"x": 10, "y": 20, "z": 30}
print(len(dic))             # 3
se = {5, 3, 8, 2, 6}
print(len(se))              # 5
len()関数は、文字列、バイト列、各コレクションの長さ(文字数/サイズ/要素数)を取得する。
要素数 = len(配列)
2025.04.26
コレクションのクリア clear()
lst = ["ABC", "DEF", "GHI"]
lst.clear()
print(lst)                  # []
dic = {"a": 10, "b": 20, "c": 30}
dic.clear()
print(dic)                  # {}
se = {2, 8, 5, 3}
se.clear()
print(se)                   # set()
ba = bytearray(b"\x01\x02\x03\x04")
ba.clear()
print(ba)                   # bytearray(b'')
リスト、辞書、セット、bytearrayのclear()メソッドは、要素をすべて削除して配列を空にする。
コレクション.clear()
2025.04.26
コレクションのコピー copy()
lst1 = ["ABC", "DEF", "GHI"]
lst2 = lst1.copy()
print(lst2)                 # ['ABC', 'DEF', 'GHI']
dic1 = {"a": 10, "b": 20, "c": 30}
dic2 = dic1.copy()
print(dic2)                 # {'a': 10, 'b': 20, 'c': 30}
se1 = {2, 7, 3, 5}
se2 = se1.copy()
print(se2)                  # {2, 3, 5, 7}
ba1=bytearray(b'\x01\x02\x03')
ba2=ba1.copy()
print(ba2)                  # bytearray(b'\x01\x02\x03')
リスト、辞書、セット、bytearray型のcopy()メソッドは、それらのコピーを作成して返す。
copy()メソッドで作られるのコピーは 「浅いコピー 」と呼ばれるコピーであり、要素がコレクション型で階層になっていても、再帰的なコピーはされない。
コピー = コレクション.copy()
2025.04.26
コレクションの要素存在チェック in/not in
lst = ["ABC", 100, "UVW", 200]
print("UVW" in lst)         # True
print(300 not in lst)       # True
tp = ("ABC", 100, "UVW", 200)
print("UVW" in tp)          # True
se = {9, 3, 5, 8, 2, 1}
print(7 not in se)          # True
dic = {"x": 10, "y": 20, "z":30}
print("a" in dic)           # False
print("a" not in dic)       # True
各コレクションに指定する要素が存在するかどうか、あるいは存在しないかどうかをin演算子/not in演算子で確認できる。結果はブール値で返る。
辞書の場合は、キーが存在するかどうかの判定になる。
確認する要素 in 各種コレクション
確認する要素 not in 各種コレクション
2025.04.26
配列のイテレーション for-in
for c in "ABCあいう":
    print(c)                # A B C あ い う
for b in  b"\x01\x02\xa0\xb0":
    print(b)                # 1 2 160 176
for n in [10, 20, 30, 40]:
    print(n)                # 10 20 30 40
for n in (10, 20, 30):
    print(n)                # 10 20 30
for s in {30, 10, 20}:
    print(s)                # 10 20 30
文字列、バイト列、コレクションのような反復可能(イテラブル)なオブジェクトは、for文により要素を順番に参照(イテレーション)できる。
for 変数 in コレクション:
    変数を使った処理
2025.04.26
辞書のイテレーション
for key in {"a": 10, "b": 20, "c": 30}:
    print(key, dic[key])
a 10
b 20
c 30
辞書のイテレーションの場合、変数は「キー」を参照する。
for 変数 in 辞書:
    変数(キー)を使った処理

辞書のキー・値ごとにイテレーション

dic = {"a": 10, "b": 20, "c": 30}
print(dic.keys())
for key in dic.keys():      # キーを反復参照
    print(key)
print(dic.values())
for val in dic.values():    # 値を反復参照
    print(val)
dict_keys(['a', 'b', 'c'])
a
b
c
dict_values([10, 20, 30])
10
20
30
辞書のkeys()メソッド、values()メソッドは、それぞれ辞書のキーのみ/値のみからなる配列オブジェクトを生成する。
その配列は反復可能(イテラブル)なのでイテレーションできる。
キーのみの配列 = 辞書.keys()
値のみの配列 = 辞書.values()

辞書のキー・値を両方取得してイテレーション

dic = {"a": 10, "b": 20, "c": 30}
print(dic.items())
for k, v in dic.items():
    print(k, v)
dict_items([('a', 10), ('b', 20), ('c', 30)])
a 10
b 20
c 30
辞書のitems()メソッドは、辞書の各要素をキーのみと値をタプルにまとめた配列オブジェクトを生成する。
その配列は反復可能(イテラブル)なのでイテレーションできる。
イテレーションで得られるタプルをアンパックすると、キーと値の両方が参照できる。
2025.04.26
順序を変えてイテレーション sorted()/reversed()
for l in sorted([3, 1, 2, 4]):
    print(l)
for t in reversed((100, 200, 300)):
    print(t)
for d in sorted({2:"A", 3:"B", 1:"C"}):
    print(d, dic[d])
1
2
3
4
300
200
100
1 C
2 A
3 B
sorted()/reversed()関数に反復可能(イテラブル)なコレクションを与えると、そのコレクションをソート/逆転した順のリストを返す。
コレクションそのものの順番を変えるのではなく、新たに整列したコレクションを返す。
辞書の場合は、キーを基準に整列する。
整列したコレクション = sorted(コレクション)
逆順のコレクション = reversed(コレクション)
2025.04.26
整数範囲のイテレーション for-in range()
for i in range(4):
    print(i)        # 0 1 2 3
for i in range(1, 4):
    print(i)        # 1 2 3
for i in range(0, 30, 10):
    print(i)        # 0 10 20
for i in range(10, 0, -2):
    print(i)        # 10 8 6 4 2
range()関数は、規則的な数列オブジェクトを生成して返す。
range()をイテレーションすることで、固定回数を繰り返す処理や、規則的な数列を使った処理が作れる。
range(回数)
range(開始値, 停止値)
range(開始値, 停止値, 間隔)
2025.04.26
イテレータで繰り返し参照 next()
it = iter([10, 20, 30, 40])
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
10
20
30
40
StopIteration
文字列、バイト列、コレクションのような反復可能(イテラブル)なオブジェクトは「イテレータ」によって先頭から順番に参照できる。
iter()関数は、反復可能なオブジェクトのイテレータオブジェクトを取得する。そのイテレータオブジェクトをnext()関数に指定して呼び出すたびに、順番に要素が参照できる。
末尾を超えて参照しようとしたときエラー(StopIteration例外)になる。
イテレータ = iter(コレクション)
次の要素 = next(イテレータ)
次の要素 = next(イテレータ)
...
2025.04.26
条件の評価で分岐 if-elif-else
s = "DEF"
if s != "ABC":
    print(s, "is not abc")

if s == "ABC":
    print(s, "is abc")
else:
    print(s, "is not abc")

if s == "ABC":
    print(s, "is abc")
elif s == "DEF":
    print(s, "is def")
else:
    print(s, "is not abc,def")
DEF is not abc
DEF is not abc
DEF is def
if文は、式の評価結果から得られるブール値によって実行する処理を分岐させることができる。
式の評価がTrueの場合は、if文以下のブロックを実行する。
if 条件式:
    条件がTrueの場合実行するブロック
    ・・・
式の結果がFalse場合は、elseに続くブロックを実行する。
if 条件式:
    条件がTrueの場合実行するブロック
    ・・・
else:
    条件がFalseの場合実行するブロック
    ・・・
elif文は、else-ifのようにifの条件がFalseの場合に、続けて別の条件を評価させることができる。
elif文は複数の条件を任意に連続させることができる。
else文とelif文は省略可能。
2025.04.26
三項演算
a = 12
x = "A" if a < 10 else "B"
print(x)        # B
三項演算は、条件式の評価結果により実行する式を分岐させる。
if文はブロックの処理を分岐させるが、三項演算は式を分岐させる。
x = Trueの式 if 条件式 else Falseの式
2025.04.26
条件がTrueの間繰り返す while
i = 0
while i < 5:
    print(i)
    i += 1
0
1
2
3
4
while文は、式の評価結果がTrueである間、ブロックの処理を繰り返し実行する。
繰り返しを終了するには、条件式がFalseになるか、break文で強制的に終了する必要がある。
while 条件式:
    条件がTrueの間繰り返すブロック
    ・・・
2025.04.26
繰り返しの強制終了 break
i = 0
while True:
    if i >= 5:
        break
    print(i)
    i += 1
0
1
2
3
4
while文やfor文の繰り返しの中でbreak文を実行すると、その時点で繰り返しを中断し、それ以降の処理を実行せずブロックから抜けることができる。
break文は、ほとんどの場合if文を伴う。
while 条件式:
    ・・・
    if 式
        break
    ・・・

breakで中断しなかった場合のelse

num = (3, 8, 2, 9)
for i in num:
    if i >= 10:
        break
    print(i)
else:
    print("num<10")
3
8
2
9
num<10
while文やfor文に対応するelse文のブロックに、繰り返し処理がbreak文によって中断しなかった場合の処理を実行させることができる。
while 条件式:
    ・・・
    if 式
        break
    ・・・
else:
    breakで中断しなかった場合の処理
    ・・・
2025.04.26
繰り返しの継続 continue
i = 0
while i < 10:
    i += 1
    if i % 2 != 0:
        continue
    print(i)
2
4
6
8
10
while文やfor文の繰り返しの中でcontinue文を実行すると、その時点でそれ以降の繰り返しの処理を放棄して、次の条件式の評価に戻すことができる。
while 条件式:
    ・・・
    if 式
        continue
    ・・・
2025.04.26
条件の評価演算
while True:
    print("true")       # 永久ループ

if not "":              # 空文字はFalseと等価
    print("not none")

a = 10
b = 20
if a > 5 and b <= 30:   # 論理演算
    print(a, b)
if a > 5 or b <= 10:
    print(a, b)
if not (a > 10 or b < 20):
    print(a, b)
true
not none
10 20
10 20
10 20
if文やwhile文は、条件式の評価結果が最終的にブール値のTrueなのかFalseなのかで分岐または繰り返す。
条件式は最終的にブール値で評価できるならば、比較演算に限らず論理演算や関数の戻り値、ブール値と等価な変数やリテラルでかまわない。条件式に直接ブール値を指定すれば、常にその条件で実行する。
while True:
    常に繰り返す
    ・・・
次のように、データの状態によってブール値と等価に評価できる。
データ True False
数値 0以外 0
文字列 空文字でない 空文字
リスト等コンテナ 内容がある 内容が空
None - None
条件式をand/or/notの論理演算で結合することで、「AまたはB」「CかつD」「Eではない」のような条件評価ができる。
2025.04.26
内包表記 [for-in]
lst = [n * 10 for n in range(0, 5)]
print(lst)

lst = [n * 10 for n in range(0, 5) if n != 3]
print(lst)
[0, 10, 20, 30, 40]
[0, 10, 20, 40]
内包表記の構文により、イテラブルな配列オブジェクトを反復参照し、それを演算などで加工して新たなコレクションを生成することができる。
通常のイテレーションで数列のリストを生成する場合おおよそ次のようになるが、内包表記ならばリストの内部で数列を生成できる。
lst = []
for n in range(0, 5):
    lst.append(n * 10)
[ 変数を使った式 for 変数 in イテラブルなオブジェクト ]
[ 変数を使った式 for 変数 in イテラブルなオブジェクト if 変数を使った条件式]
これらはfor文で次のように置き換えられる。
for n in イテラブルな配列:
    nを使った式

for n in イテラブルな配列:
    if nを使った条件式:
        nを使った式

辞書・セットの内包表記

dic = {n: n * 10 for n in range(0, 5)}
print(dic)      # {0: 0, 1: 10, 2: 20, 3: 30, 4: 40}

tp = (("A", 10), ("B", 20), ("C", 30))
dic = {k: v for k, v in tp}
print(dic)      # {'A': 10, 'B': 20, 'C': 30}
リストと同様に辞書を内包表記で生成できる。キーと値の組み合わせで初期化する。
{ キー:値 for 変数 in イテラブルなオブジェクト }
se = {n for n in range(0, 5)}
print(se)       # {0, 1, 2, 3, 4}
また同様にセットを内包表記で生成できる。
{ 値 for 変数 in イテラブルなオブジェクト }
2025.04.26
なにもしない処理 pass
if a > 10:
    pass    # なにもしない(空行にはできない)
else:
    print(a)

def funcdummy():    # 処理がない関数
    pass
pass文は何もしない。
インタプリタはソースコード構造を解析できないので、if文や関数的などでブロックが続くことが期待される構文では、ブロックで実行する処理がなくても何らかの文が続かなくてはならない。
2025.04.26
関数定義 def
def func(arg1, arg2):
    x = (arg1 + arg2) / 2
    print(x)
    return x
def文により関数を定義する。defに続き、関数名と引数リストを定義する。
関数名と引数名は、変数名と同じ命名規則に従う。関数の処理をインデントによるブロックで記述する。
引数のデータ型は関数呼び出しで与えられたデータで決定するので指定しなくてよい。引数が不要ならば省略できる。
関数はreturn文で戻り値を返却する。戻り値の型は定義せず、return文で戻るデータで決定する。
return文の戻り値は省略でき、その場合は戻り値を返さずに関数が返る。return文は定義中に複数存在してかまわない。関数のブロックの最後に達した時点でreturn文がなくても自動的に返る。
def 関数名(引数, 引数, ...):
    処理
    ...
    return 戻り値
def 関数名():   ※引数なし
    ...
    return      ※戻り値なし
    ...
    if (..)
        return      ※複数個所でreturn
    ...

    ...         ※ブロック末尾で自動的に返る
2025.04.26
関数呼び出し
def func1():
    print("Invoked")

func1()         # Invoked

def func2(a):
    x = a * 10
    return x

a = func2(5)
print(a)        # 50

def func3(a, b):
    return a * b

x = func3("A", 5)
print(x)        # AAAAA
関数定義した関数は、定義された引数に従った引数を与えて関数名で呼び出す。
引数のない関数は引数を指定せずに呼び出す。
戻り値が返る関数は、関数呼び出し自体が戻り値を参照している。
関数の戻り値を変数に代入したり、演算子の中に含めたり、コレクションの初期化要素にできる。
関数名(引数, 引数,...)
関数名( )
2025.04.26
戻り値のアンパック
def calc(x, y):
    m = x * y
    a = x + y
    s = x - y
    return  m, a, s

c = calc(9, 5)
print(c)            # (45, 14, 4)

a, b, c = calc(3, 8)
print(a, b, c)      # 24 11 -5
戻り値はreturn文で1つのオブジェクトしか返却できないが、リストやタプルを戻り値にすれば、実質的に複数データをまとめて返却できる。呼び出し側がアンパックで戻り値を代入すれば、複数戻り値を返す関数のような振る舞いになる。
2025.04.26
デフォルト引数
def func(a, b = 10):
    return a * b

x = func(3)
print(x)        # 30
x = func(3, 2)
print(x)        # 6
関数の定義で引数にデフォルト値を指定すると、その引数は関数呼び出し時に省略できるようになる。
省略した引数はデフォルト値が自動的に与えられる。省略しない場合は呼び出しで与えられたものが適用される。
def 関数(引数1=デフォルト値, 引数2=デフォルト値, ...):
デフォルトを設定した引数以降は、全てデフォルト引数で定義しなければならない。また、呼び出し側が省略できるのは末尾側であり、省略した後に省略しない引数を続けることはできない。
2025.04.26
キーワード引数
def func(a, b = 20, c = 10):
    return a * b / c

x = func(10, c=4)
print(x)                # 50.0
x = func(10, b=2)
print(x)                # 2.0
x = func(c = 2, a = 4)
print(x)                # 40.0
キーワード引数により、関数呼び出し時の引数を、関数定義の順番(位置引数)に従わず順不同に指定することができる。
キーワード引数は、関数呼び出し時の引数に「引数名=値」のように指定する。
ret = 関数(引数名2=値, 引数名1=値, ...)
順不同に指定できるキーワード引数に対して、定義順に指定する通常の引数指定を位置引数と呼ぶ。
引数の先頭から位置引数を与え、途中からキーワード引数で呼び出すこともできる。
ret = 関数(引数1, 引数2, 引数4=値, 引数3=値)
キーワード指定した引数から右に定義されている引数でデフォルト設定されてないものは、すべてキーワード引数で呼び出す必要がある。
全ての引数にデフォルト値を定義すると、キーワード引数により必要な引数だけを選んで呼び出すことができる。
2025.04.26
引数のタプル参照 *args
def func(*args):
    for x in args:
        print(x)        # 'A' 20

func("A", 20)
関数定義で引数名の頭に「*」付けた引数は、それ以降の引数をタプルでまとめて参照できる。
このような引数を定義するときは一般的に「args」という名前にする習慣がある。
def 関数(*args):
    argsは引数列のタプル

位置引数とタプル参照を両方定義

def func(a, *args):
    for x in args:
        print(x * a)    # 50 80 30 

func(10, 5, 8, 3)
先頭側は位置引数で、途中以降からタプルの引数にできる。この場合、位置引数はタプルの中には含まれない。

関数呼び出しにタプルを与え引数展開

def func(a, b, c):
    print(a, b, c)      # 10 20 30

tp=(10, 20, 30)
func(*tp)
呼び出し側でタプルに「*」をつけて引数に与えることで、タプルの要素を展開して引数に与えることができる。
タプル = (引数1, 引数2, ...)
x = 関数(*タプル)
2025.04.26
引数の辞書参照 **kwargs
def func(**kwargs):
    print(kwargs)       # {'arg1': 'A', 'arg2': 20}

func(arg1="A", arg2=20)
関数定義で引数名の頭に「**」付けた引数は、キーワード引数で渡された引数を辞書として参照できる。辞書のキーが変数名で、値が引数の値である。
このような引数を定義するときは一般的に「kwargs」という名前にする習慣がある。
def 関数(**kwargs):
    argsは引数の辞書

位置引数とタプル参照と辞書参照の混在

def func(a, b, *args, **kwargs):
    print(a, b)     # 10 20
    print(args)     # (30,)
    print(kwargs)   # {'d': 40} 10と20と30は含まれない

func(10, 20, 30, d=40)
def func(a, b, *args, **kwargs):
    print(a, b)     # 10 20
    print(args)     # ()
    print(kwargs)   # {'c': 30, 'd': 40} b=20は含まれない

func(10, b=20, c=30, d=40)
kwargsは位置引数をキーワードで指定されたものは含まれない。同様にタプルで参照するargsも位置引数は含まれない。
引数のタプルと辞書を組み合わせれば、あらゆる与え方の引数をargsのタプルかkwargsの辞書のいずれかで参照できる。
def 関数(*args, **kwargs):
    すべての引数をargsかkwargsで参照できる

関数呼び出しに辞書を与え引数展開

def func(a, b):
    print(a, b)     # 20 30

dic = {"a":20, "b":30}
func(**dic)
呼び出し側で辞書に「**」をつけて引数に与えることで、辞書のキーを引数名として展開して引数に与えることができる。
辞書 = {"引数1":値1, "引数2":値2, ...}
x = 関数(**辞書)
2025.04.26
関数オブジェクト
def func():
    print("ABC")

f = func
f()             # ABC

def func1():
    print("ABC")

def func2():
    print("OPQ")

flst = [func1, func2]
flst[0]()       # ABC
flst[1]()       # OPQ
定義した関数を変数に代入し、その変数を関数として呼び出すことができる。
関数定義はデータと同様にオブジェクトとして扱うことができ、例えばリストの要素にもできる。
変数 = 関数名
変数名(引数)

関数定義を関数の引数に与える

def add(a, b):
    return a + b

def calc(func, a, b):
    return func(a, b)

x = calc(add, 7, 10)
print(x)        # 17
関数定義は、関数の引数に与えることができる。
2025.04.26
ラムダ式(無名関数) lambda
f = lambda x: x * 10
print(f(7))     # 70
ラムダ式は、lambdaに続く引数とひとつの文からなる関数を即時に生成する。
def文による関数定義とは異なり無名関数なので、関数名で繰り返し呼び出すことはできない。ラムダ式を変数などに代入して参照を保持しなければ、その場で定義は消滅する。
lambda 引数, 引数,…: 式

ラムダ式を定義即呼び出し

a = (lambda x, y: x * y)(7, 10)
print(a)        # 70
ラムダ式を変数に代入せずに、定義してすぐに呼び出すことができる。
2025.04.26
関数の関数内定義
def func(a):
    def ifunc(x):
        print ("x =", x)
    ifunc(a)
func(10)        # x = 10 
関数定義の中で関数を定義できる。関数定義のブロックで、中で定義した関数を呼び出すことができる。
def func():
    def ifunc(x):
        print ("x =", x)
    return ifunc
rf = func()
rf(10)      # x = 10 
関数定義の中で定義した関数を、戻り値として呼び出し元に返すことができる。呼び出し側では、その戻り値を関数オブジェクトとして呼び出すことができる。
2025.04.26
関数と変数のスコープ
def add(a, b):
    x = a + b       # subのxとは関係ない
    return x

def sub(a, b):
    x = a - b       # addのxとは関係ない
    return x
関数定義の中の変数は関数定義の中だけにスコープが限定される。同名の変数名がほかの関数定義で使われていても、それらは関数のローカルスコープで閉じている。

関数内のグローバル変数の変更

name = "Brown"
def func1():
    print(name)
func1()             # Brown

def func2(n):
    name = n        # ローカル変数nameを生成
    print(name)     # James
func2("James")
print(name)         # Brown

def func3(n):
    global name
    name = n        # グローバル変数の変更
    print(name)     # James
func3("James")
print(name)         # James
関数定義内で関数外の変数「グローバル変数」を変更する場合は、関数定義の先頭でglobal宣言する必要がある。
関数定義内でグローバル変数は参照できる。しかし関数定義内でグローバル変数への代入などで変更しようとすると、その変数はローカル変数として新たに生成されてしまうので、グローバル変数の変更にはならない。
global宣言は、それが関数外のものであることをインタプリタへ明示する。
def 関数():
    global グローバル変数名
    グローバル変数 = ...
2025.04.26
例外の捕捉 try-except
try:
    a = 10/0
    print(a)    # 直前で例外なので実行されない
except:
    print("Exception")
print("Continue")
Exception
Continue
スクリプトの実行を継続できない事象が発生したとき「例外」が送出される。例外送出時は標準ではスクリプトの実行が直ちに停止する。
スクリプトの任意の区間で送出される例外を捕捉して、それに対処する処理ブロックへジャンプさせることでスクリプトを止めずに継続させることができる。
try文からexcept文の間を例外発生を監視し、その区間で例外発生したときは直ちにexcept文のブロックへジャンプする。exceptのブロックを実行した後は、try-exceptから出て処理が続行される。
try:
    例外を捕捉したい処理区間
except:
    例外発生時の処理

例外のelseブロックとfinallyブロック

try:
    a = 10/0
except:
    print("zero div")
else:
    print("No error")
finally:
    print("Done")
zero div
Done
try-exceptの区間で例外が発生しなかった場合のみ実行する処理をelseブロックに記述できる。
また、exceptで補足した場合とそうでないelseブロックを実行した場合の両方の場合に共通して最後に実行する処理を、finallyブロックに記述できる。
2025.04.26
指定の例外を捕捉
try:
    a = 10/1
    print(a)
    d = {"AB":20}
    print(d["CD"])
except ZeroDivisionError:
    print("zero div")
except Exception as e:
    print(type(e))
<class 'KeyError'>
例外は、プロセス終了を除く発生の要因ごとに、Exceptionクラスをスーパークラスとするサブクラスとして定義されている。
exceptに続けて例外クラス名を指定すると、その例外のみを捉える。またExceptionクラスを指定すると、全ての例外が補足できる。
except 例外クラス名:    ※指定する例外
except:                 ※すべての例外
except Exception:       ※すべての例外
補足した例外クラスのインスタンスをasに続く変数に格納することができる。
その変数をprint()で表示したり、type()でクラス名を調べることで例外の詳細を知ることができる。
except 例外クラス名 as 変数:

主な例外クラス

例外 例外の説明
KeyboardInterrupt Ctrl-Cが入力された
StopIteration これ以上反復する要素がない(next()関数が終端に達したなど)
ArithmeticError 算術演算関係のエラー
  OverflowError 計算結果が表現しきれない大きい値になった
  ZeroDivisionError 0での割り算が行われた
AttributeError 属性の参照や代入でのエラー(ImportErrorが出る状況と似ている)
EOFError input()の入力待ちでEOF(Ctrl-zやCtrl-d)になった
ImportError インポート失敗(モジュールと同名ファイルが競合しているなど)
LookupError キーや添字の参照で違反
  IndexError 添字が範囲外
  KeyError キーが存在しない
NameError ローカル・グローバルに名前が見つからなかった
OSError システム関係のエラー
  FileExistsError 既に存在するファイルを作成しようとした
  FileNotFoundError ファイルやディレクトリが存在しない
  PermissionError ファイル操作のアクセス権違反
  TimeoutError システム関数がタイムアウトした
RuntimeError 分類できないエラー
SyntaxError 文法エラー
  IndentationError インデントが正しくない
TypeError データ型の不一致(整数と文字列で足し算しようとしたなど
ValueError 値が異常(数値を表していない文字列を数値変換しようとしたなど
2025.04.26
ライブラリをインポート import
import math

print(math.pow(5, 2))       # 25.0
import文により、Pythonにインストールされているライブラリ(パッケージ)のモジュール名を指定しインポートできる。
インポートしたモジュールの内容は、それ以降のスクリプトで利用できる。モジュール名を名前空間として、そのモジュールの定義されたクラス、関数、変数を参照できる。
import モジュール名

モジュール名.クラス
モジュール名.関数()
モジュール名.変数
2025.04.26
モジュール名の省略 from-import
from math import pow, sqrt, pi

print(pow(5, 2))        # 25.0
print(pi)               # 3.141592653589793
print(sqrt(2))          # 1.4142135623730951
import文でインポートしたモジュールを利用するとき、デフォルトではモジュール名の名前空間を指定する必要がある。
from~import文により、モジュールから参照したいシンボル名(関数、クラス、変数)を明示的に指定することで、利用時にそれらのモジュール名を省略できる。
from モジュール名 import 関数, クラス, 変数, ... 
列挙するシンボル名を「*」で置き換えると、そのモジュール内の全てを一括指定できる。
その場合、そのモジュールを現在のスクリプトに書き写したかのように使うことができる。
from モジュール名 import * 
2025.04.26
モジュール名の別名 import-as
import math as m

print(m.pow(5, 2))      # 25.0
print(m.pi)             # 3.141592653589793
インポートするモジュールを別名を付けて参照できる。インポートするモジュールのパッケージを含めた長い名前が書きやすくなる。
import モジュール名 as 別名
2025.04.26
コマンドライン引数の参照 sys.argv
import sys

print(len(sys.argv))
for arg in sys.argv:
    print(arg)
$ python3 cmd.py aaa 123 xxx
4
cmd.py
aaa
123
xxx
Pythonを実行するとき、コマンドラインにパラメータを指定できる。
コマンドラインパラメータは、sysモジュールのsys.argvから文字列のリストとして参照できる。sysモジュールをインポートする必要がある。
sys.argvのリストは先頭からpython3コマンドに続けて指定したものがそのまま格納される。スクリプトファイルでは、先頭のsys.argv[0]はそのファイル名になる。
import sys
sys.argv[0]     スクリプトファイル名
sys.argv[1]     引数1
sys.argv[2]     引数2
2025.04.26
キーボードからの入力 input()
a = input()
print("input:", a)

a = input("???-->")
print("input:", a)
abcdefg
input: abcdefg
???-->123456
input: 123456
input()関数はキーボードからの入力を取り込む。
input()関数が呼び出されると、キーボードからの入力待ち状態になる。テキストをキーボードから入力して[Enter]を押すとinput()が返り、戻り値に入力した文字列が返る。戻り値には、最後の[Enter]の改行文字は含まれない。
引数にメッセージの文字列を指定できる。メッセージを表示した横にカーソルが現れて入力待ちになる。
入力文字列 = input(メッセージ文字列)
2025.04.26
文字列の標準出力 print()
print("Messageメッセージ")
print([100, 200, 300])
a = (10, 20)
print(a)
Messageメッセージ
[100, 200, 300]
(10, 20)
print()関数は、文字列を標準出力へ出力(表示)する。
引数には数値、文字列、変数など任意のオブジェクトを「,」で区切って複数指定できる。文字列を与えた場合はそのまま出力し、文字列以外はそれぞれのデータ型を文字列に変換して出力する。
print(オブジェクト, オブジェクト, ...)
a = (10, 20)
b = "ABC"
print(a, b, 666)
print(a, b, 666, sep = ',')
print("Message", end = "")
print("[newline]")
(10, 20) ABC 666
(10, 20),ABC,666
Message[newline]
末尾の引数に「sep=文字」を指定すると出力の区切り文字を変更できる。print()は自動的に改行になる。末尾の引数に「end=文字」とすることで改行に代わる終端文字を指定できる。それに空文字を指定すると改行しなくなる。
print(オブジェクト, オブジェクト, ..., sep="区切り文字")
print(オブジェクト, オブジェクト, ..., end="末尾文字")
print(オブジェクト, オブジェクト, ..., end="")  ※改行しない
クラス
2025.04.26
クラスの定義 class
class Clsname:
    pass
クラスは、データを属性として変数を保持し、振舞いをメソッドとして関数を定義する。数値や文字列などの各データ型はそれぞれのクラスで定義されている。
class文に続き任意のクラス名の、独自のクラスを定義する。クラス名は変数名と同じ命名規則で任意につけることができる。定義の内容はブロックとしてインデントする。
class クラス名:
    メソッドや属性の定義
    ...
2025.04.26
インスタンスの生成
class Clsname:
    pass

c = Clsname()
print(c)
<__main__.Clsname object at 0x7f5273c12bf0>
クラス名を関数のように呼び出すと、クラスのインスタンス(実体)が生成され返る。
クラス名()
変数 = クラス名()
2025.04.26
属性の作成
class Cls:
    pass

a = Cls()
a.x = 100
a.y = 200
print(a.x, a.y)         # 100 200
インスタンスに「.(ドット)」で区切り任意の変数名を記述すると、その変数名がインスタンスの属性として追加される。その属性にデータを代入することで、そのインスタンスにデータが格納される。
このように、クラスから生成するインスタンスごとに、動的に属性を加えることができる。
インスタンス.属性 = 値
2025.04.26
メソッドの定義と呼び出し
class Msg:
    def show(self, msg):
        print("message:" +  msg)

m = Msg()
m.show("Hello")         # message:Hello
クラス定義に関数を定義すると、その関数はクラスのメソッドになる。
メソッドとして定義する関数は、必ず先頭に1つの引数を定義する。先頭の引数は「現在のインスタンス」を参照する(慣習としてselfという名前が使われている)。引数のない関数でも最低1の引数を持つことになる。
def 関数名(self):
def 関数名(self, 引数, 引数,...):
クラスに定義されてたメソッドは、そのクラスのすべてのインスタンスから呼び出すことができる。インスタンスに「.(ドット)」で区切って関数のように呼び出す。
メソッドの呼び出しでは、クラスに定義した先頭の引数(self)は渡す必要はない。呼び出し時に、内部的にインスタンスの参照が先頭の引数に渡る。
インスタンス.メソッド(引数, 引数, ...)
2025.04.26
メソッドから属性を参照
class Cls:
    def setattr(self, n, m):
        self.x = n          # selfはcを指す
        self.y = m

c = Cls()
c.setattr(100, "ABC")       # cがselfに渡る
print(c.x, c.y)             # 100 ABC
インスタンスの属性をメソッドの中で生成できる。
インスタンスを参照する先頭の引数(self)に「.変数名」のように続けると、インスタンスの属性の参照になる。変数名が新規ならば属性の追加になる。
def method(self, ...):
    self.属性名 = 値
2025.04.26
メソッドからメソッドを呼び出し
class Cls:
    def set(self, a):
        self.s = a
    def get(self):
        return self.s
    def show(self):
        print("attr:", self.get())

c = Cls()
c.set("ABC")
c.show()                    # attr: ABC
メソッドの中から他のメソッドを呼び出すことができる。
インスタンスを参照する先頭の引数(self)に「.メソッド()」として、インスタンスのメソッドを呼び出す。
def method(self, ...):
    self.othermethod(...)
2025.04.26
コンストラクタ __init__
class Cls:
    def __init__(self, a):
        self.x = a
        print("new Cls:", a)
    def show(self):
        print("attr:", self.x)

c = Cls("ABC")
c.show()
new Cls: ABC
attr: ABC
__init__()というメソッドで、クラスのコンストラクタを定義する。
コンストラクタの__init__()メソッドは、インスタンスの生成時に自動的に呼び出される。インスタンス生成時の引数が__init__()に渡される。通常のメソッドと同様、定義の先頭の引数はインスタンスを参照している。
コンストラクタにより、クラスのインスタンスの初期の属性の生成や、初期化処理ができる。
def __init__(self, 引数, 引数,...):
__init__()を明示的に定義しない場合は、何もしないコンストラクタが暗黙に呼び出される。
2025.04.26
複数クラスのインスタンスを作成
class Cls:
    def showx(self):
        print("attr:", self.x)

c1 = Cls()
c1.x = 100
c2 = Cls()
c2.x = 200
c1.showx()              # attr: 100
c2.showx()              # attr: 200
c2.y = "ABC"
print(c2.y)             # ABC
print(c1.y)             # AttributeError
クラスから生成するインスタンスは、それぞれの実体として独立したオブジェクトである。インスタンスの変数に属性を追加した場合は、そのインスタンスのみへの追加になる。一方で、クラスに定義したメソッドは、どのインスタンスでも呼び出すことができる。

コンストラクタでインスタンスを初期化

class Cls:
    def __init__(self, a):
        self.x = a
    def show(self):
        print("attr:", self.x)

c1 = Cls("ABC")
c2 = Cls("DEF")
c1.show()               # attr: ABC
c2.show()               # attr: DEF
インスタンス生成時に、コンストラクタ__init__()に定義した処理が実行される。コンストラクタに引数を与えることで、インスタンスごとに初期化できる。
2025.04.26
クラスの継承による拡張
class CSuper:
    def setx(self, a):
        self.x = a

class CSub(CSuper):
    def setxy(self, a, b):
        self.setx(a)            # CSuperのsetx()
        self.y = b
    def show(self):
        print(self.x, self.y)   # CSuperの属性xを参照

c = CSub()
c.setxy(100, 200)
c.show()                # 100 200
クラスが、既存のクラスの定義を引継ぎ(継承)、新たに属性やメソッドを加えて拡張することができる。
継承される元になるクラスをスーパークラスと呼び、それを継承して拡張するクラスをスーパークラスに対するサブクラスと呼ぶ。
クラス定義のクラス名に続き「(スーパークラス名)」のように指定し、任意のクラスを継承する。
class サブクラス名(スーパークラス名):
サブクラスは、スーパークラスの定義を自身の中で定義したように取り込む。

インスタンスからスーパークラスのメソッド呼び出し

class CSuper:
    def setx(self, a):
        self.x = a

class CSub(CSuper):
    def sety(self, a):
        self.y = a
    def show(self):
        print(self.x, self.y)

c = CSub()
c.setx(100)             # CSuperのメソッドを呼び出す
c.sety(200)
c.show()                # 100 200
c.x = 150
c.show()                # 150 200
サブクラスとして生成したインスタンスから、スーパークラスの属性の参照や、スーパークラスのメソッドの呼び出しができる。
2025.04.26
コンストラクタの継承
class CSuper:
    def __init__(self, a):
        self.x = a

class CSub(CSuper):
    def sety(self, a):
        self.y = a
    def show(self):
        print(self.x, self.y)

c = CSub(100)           # CSuperの__init__()
c.sety(200)
c.show()                # 100 200
サブクラスはスーパークラスのコンストラクタ__init__()を継承する。
サブクラスのインスタンス生成時に、サブクラスのコンストラクタが定義されておらず、スーパークラスに定義があればそれが呼び出される。
2025.04.26
メソッドのオーバーライド
class CSuper:
    def set(self, a):
        self.x = a

class CSub(CSuper):
    def set(self, a, b):    # オーバーライド
        self.x = a
        self.y = b
    def show(self):
        print(self.x, self.y)

c = CSub()
c.set(100, 200)         # CSubのset()
c.show()                # 100 200
c.set(300)              # TypeError CSuper側は呼び出されない
スーパークラスと同じメソッドをサブクラスで定義した場合、サブクラスのインスタンスからそのメソッドを呼び出すと、サブクラス側が呼び出される。
サブクラスがスーパークラスのメソッドを上書きしたようになる(オーバーライド)。

スーパークラス側のメソッドを明示的に呼び出す

class CSuper:
    def set(self, a):
        self.x = a

class CSub(CSuper):
    def set(self, a, b):    # オーバーライド
        super().set(a)      # CSuperのset()を呼び出す
        self.y = b
    def show(self):
        print(self.x, self.y)

c = CSub()
c.set(100, 200)         # CSubのset()
c.show()                # 100 200
サブクラスの中で、super()により明示的にスーパークラス側のメソッドを呼び出すことができる。
super().メソッド(引数, 引数,...)

クラス名でスーパークラスのメソッドを明示的に呼び出す

class CSuper:
    def set(self, a):
        self.x = a

class CSub(CSuper):
    def set(self, a, b):        # オーバーライド
        CSuper.set(self, a)     # CSuperのset()を呼び出す
        self.y = b
    def show(self):
        print(self.x, self.y)

c = CSub()
c.set(100, 200)         # CSubのset()
c.show()                # 100 200
クラス名に「.(ドット)」を続けてメソッドを呼び出すことで、呼び出すメソッドのクラスを直接指定できる。この場合は、先頭の引数に現在のインスタンス(self)を渡す必要がある。この方法でスーパークラスを指定してメソッドを呼び出すことができる。
スーパークラス名.メソッド(self, 引数, 引数,...)
2025.04.26
コンストラクタのオーバーライド
class CSuper:
    def __init__(self, a):
        self.x = a

class CSub(CSuper):
    def __init__(self, a, b):   # オーバーライド
        super().__init__(a)     # CSuperの__init__()を呼び出す
        self.y = b
    def show(self):
        print(self.x, self.y)

c = CSub(100, 200)
c.show()                # 100 200
サブクラスはスーパークラスのコンストラクタをオーバーライドできる。サブクラスのインスタンスの生成時にはサブクラスに__init__()メソッドの定義があれば、それを実行する。
オーバーライドしたコンストラクタからスーパークラスの初期化を実行するために、super()により明示的にスーパークラス側のコンストラクタを呼び出すことができる。
super().__init__(引数, 引数,...)
2025.04.26
多重継承
class CSuperA:
    def set(self, a):
        self.x = a

class CSuperB:
    def set(self, a):
        self.y = a

class CSub(CSuperA, CSuperB):
    def set(self, a, b, c):
        CSuperA.set(self, a)        # CSuperAのset()を呼び出す
        CSuperB.set(self, b)        # CSuperBのset()を呼び出す
        self.z = c
    def show(self):
        print(self.x, self.y, self.z)

c = CSub()
c.set(100, 200, 300)    # CSubのset()
c.show()                # 100 200 300
複数のスーパークラスを同時に継承することができる(多重継承)。
サブクラスの定義に、カンマで区切って複数のスーパークラスを指定する。
class サブクラス名(スーパークラス名, スーパークラス名,...):
多重継承の場合は、サブクラスのメソッドからスーパークラスのメソッドを呼び出すとき、super()ではスーパークラスが特定できないので、クラス名を明示する方法で呼び出す必要がある。
2025.04.26
クラス属性

クラス属性

class Cls:
    sum = 0
    def __init__(self, a):
        self.x = a
        Cls.sum += a

print(Cls.sum)              # 0 定義時から存在する
c1 = Cls(3)
print(c1.x, c1.sum)         # 3 3 c1.sumはCls.sumと同じ
c2 = Cls(5)
print(c2.x, c2.sum)         # 5 8 c2.sumはCls.sumと同じ
クラス定義に変数の代入式を記述すると、その変数はクラス属性としてクラス定義時から存在する属性となる。クラス属性は、どのインスタンスにも属さないクラスで唯一の属性になる。
class クラス:
    変数 = 初期値
クラス属性は、どのインスタンスからも唯一の属性を参照する。インスタンス属性とクラス属性が同名の場合は、インスタンスはインスタンス属性を参照する。「クラス名.属性」は必ずクラス属性の参照になる。
クラス名.属性

動的に生成するクラス属性

class Cls:
    def __init__(self, a):
        self.x = a
        Cls.sum += a

Cls.sum = 0
print(Cls.sum)              # 0 Clsにsumが生成 
c1 = Cls(3)
print(c1.x, Cls.sum)        # 3 3
c2 = Cls(5)
print(c2.x, Cls.sum)        # 5 8
クラス定義以降で「クラス名.属性」に初期値を代入すると、そのクラスのクラス属性として動的に生成される。
2025.04.26
クラスメソッド
class Cls:
    sum = 0
    @classmethod
    def addsum(cls, a):
        cls.sum += a
    @classmethod
    def getsum(cls):
        return cls.sum
    def __init__(self, a):
        self.x = a
        Cls.addsum(a)

c1 = Cls(3)
print(c1.x, c1.getsum())        # 3 3
c2 = Cls(5)
print(c2.x, c2.getsum())        # 5 8
クラス定義で、@classmethodデコレータに続いて定義するメソッドはクラスメソッドとして定義される。クラスメソッドは、クラスの名前空間に唯一定義される、どのインスタンスにも属さないメソッドになる。そのため、クラスメソッドの処理ではインスタンス属性やインスタンスのメソッドは参照・呼び出しができない。
クラスメソッドは、必ず先頭に1つの引数を定義する。先頭の引数は「クラス」への参照である(慣習としてclsという名前が使われている)。
@classmethod
def クラスメソッド(cls, 引数, 引数,...):
クラスメソッドは、どのインスタンスからも唯一のメソッドを呼び出す。「クラス名.クラスメソッド()」はあらゆる場所から唯一のクラスメソッドを呼び出す。
クラス名.クラスメソッド(引数, 引数,...)
2025.04.26
ゲッター・セッターメソッド
class Cls:
    def getx(self):
        return "---" + self._attrx      # _attrxが内部属性
    def setx(self, x):
        self._attrx = x + "---"
    attrx = property(getx, setx)

c1 = Cls()
c1.attrx = "ABC"
print(c1.attrx)         # ---ABC---
c2 = Cls()
c2.attrx = "DEF"
print(c2.attrx)         # ---DEF---
インスタンスの属性への設定や参照を、get()やset()のようなメソッドを用意して直接参照させないようにする方法があるが、属性への代入と参照時に自動的にそのようなゲッター・セッターメソッドを呼び出してアクセスさせることが可能である。
属性に対するゲッター・セッターメソッドをそれぞれ定義し、それらをproperty()関数に指定して呼び出し、戻り値を「仮の属性名」に代入する。
仮の属性名 = property(ゲッターメソッド, セッターメソッド)
インスタンスは仮の属性名で通常の属性のように参照や代入操作を行う。そのとき、自動的に参照操作はゲッターメソッド、代入操作はセッターメソッドが呼び出される。
ゲッターメソッドとセッターメソッドの中では、仮ではない実際のインスタンス属性への操作などを実装する。
インスタンス.仮の属性名         (ゲッターメソッドの呼び出し)
インスタンス.仮の属性名 = 値    (セッターメソッドの呼び出し)
このように、インスタンスから属性を直接操作するようなアクセスから保護できる。

デコレータによるゲッター・セッターメソッド

class Cls:
    @property
    def attrx(self):
        return "---" + self._attrx
    @attrx.setter
    def attrx(self, x):
        self._attrx = x + "---"

c1 = Cls()
c1.attrx = "ABC"
print(c1.attrx)         # ---ABC---
c2 = Cls()
c2.attrx = "DEF"
print(c2.attrx)         # ---DEF---
もう一つの方法として、ゲッターメソッドとセッターメソッドを、デコレータでメソッドを修飾することで定義できる。
ゲッターメソッドとして定義するメソッドを@propertyデコレータで修飾し、セッターメソッドとして定義するメソッドを@仮の属性名.setterデコレータで修飾する。そして、それらのメソッドはどちらも「仮の属性名()」の同じメソッド名で定義する。
@property
def 仮の属性名(self):
    return 属性

@仮の属性名.setter
def 仮の属性名(self, 引数, 引数,...):
2025.04.26
命名法によるアクセス制限
class Cls:
    def get(self):
        return "---" + self._attrx
    def set(self, x):
        self._attrx = x + "---"

c = Cls()
c.set("ABC")
print(c.get())          # ---ABC---
Pythonの慣習として、アンダーバー(アンダースコア)からはじまる属性は、プライベートであるとしてインスタンスから直接参照しないというPython開発者間のルールがある。ただし、ルールを無視すれば参照は可能である。

難読化(マングリング)によるアクセス制限

class Cls:
    def get(self):
        return "---" + self.__attrx
    def set(self, x):
        self.__attrx = x + "---"

c = Cls()
c.set("ABC")
print(c.get())                  # ---ABC

c._Cls__attrx = "---ABC---"
print(c._Cls__attrx)            # ---ABC
「__」から始まる属性名は、インタプリタが内部的に別の名前に変換(難読化)するため、定義上のスペルではアクセスできなくなる。ただし次のような変換法則なので決して強い難読化ではない。
__属性名 ⇒  _クラス名__属性名
2025.04.26
演算子のオーバーロード
class Cls:
    def __init__(self, a):
        self.x = a
    def __add__(self, c):
        return self.x + "-!-" + c.x

c1 = Cls("ABC")
c2 = Cls("DEF")
print(c1 + c2)              # ABC-!-DEF

c1.__add__(c2)
print(c1 + c2)              # ABC-!-DEF
クラスのインスタンスに対して演算子で演算が行われようとしたときに、そのクラスの特性に対応した演算処理を実装する特殊メソッドが存在する。例えば文字列の「+」による加算は、文字列クラスとしての加算メソッドの実装により文字列の連結が行われる。
演算子による演算時に呼び出されるそれらの特殊メソッドを実装(オーバーロード)することで、定義したクラスのインスタンスの変数を使った演算ができるようになる。
演算子の特殊メソッドは「__演算__」のような名前になっている。特殊メソッドの第一引数は自身のインスタンス(self)で、二項演算ならば右項のインスタンスを第二引数で受ける。例えば加算演算のオーバーロードは、__add__()という特殊メソッドを実装する。
def __add__(self, インスタンス右項):

インスタンス左項.__add__(self, インスタンス右項)

文字列化のオーバーロード

class Cls:
    def __init__(self, a):
        self.x = a
    def __str__(self):
        return "<<" + str(self.x) + ">>"

c = Cls(123)
print(str(c))           # <<123>>
str()関数はクラスのインスタンスをそれぞれの形式で何らかの文字列に変換する。このとき、クラスのインスタンスに対し特殊メソッドの__str__()が呼び出される。
__str__()メソッドを定義して実装することで、インスタンスがstr()関数に渡されたときに適当な文字列を返すことができる。
__str__()メソッドは自身のインスタンス(self)のみ引数に取る。
def __str__(self):

文字例 = インスタンス.__str__(self)
2025.04.26
その他の特殊メソッド
操作 特殊メソッド 使い方
加算 __add__(self, other) self + other
減算 __sub__(self, other) self - other
乗算 __mul__(self, other) self * other
除算 __truediv__(self, other) self / other
切り捨て除算 __floordiv__(self, other) self // other
剰余 __mod__(self, other) self % other
べき乗 __pow__(self, other) self ** other
イコール __eq__(self, other) self == other
ノットイコール __ne__(self, other) self != other
小なり __lt__(self, other) self < other
大なり __gt__(self, other) self > other
小なりイコール __le__(self, other) self <= other
大なりイコール __ge__(self, other) self >= other
文字列に変換 __str__(self) str(self)
長さ __len__(self) len(self)
ファイル入出力
2025.04.26
ファイルのオープン・クローズ open() close()
f = open("test.txt", "r")
data = f.read()
f.close()
print(data)
ABCDEFG
あいうえお
123456789
open()関数は、指定されるモードに従いファイルを開き、ファイルオブジェクトを戻り値に返す。
ファイルオブジェクト = open(ファイルパス, モード)
ファイルオブジェクト = open(ファイルパス, モード, encoding="文字コード")
ファイルパスは、パスを含めたファイル名を文字列で指定する。
指定するファイルが存在しない場合は、モードによって新規作成または例外の何れかになる。
モードには、読み出しは「r」、書き込みは「w」のようなファイルの開き方を文字で指示する。モードを省略した場合は読み出しの「r」が適用される。
encoding引数に文字コードを指定できる。
文字コードには、「utf-8」「shift_jis」「euc_jp」などが指定できる。省略した場合は、動作しているOSに従って自動的に選択される。
戻り値で返るファイルオブジェクトのメソッドにより、開いたファイルに対する各種操作を行う。
ファイルオブジェクト.メソッド(引数)
close()メソッドでファイルを閉じてアクセスを終了する。
ファイルオブジェクト.close()

オープンモード

モードには、開くファイルへの操作ごとに以下を指定する。
モード 既存ファイルなし時の
open()の結果
既存ファイルあり時の
open()の結果
読み出し
可・不可
書き込み
可・不可
r エラー 成功 可能 不可
r+ エラー 成功 可能 可能(上書き)
w 成功(新規作成) 成功 不可 可能
w+ 成功(新規作成) 成功(内容破棄) 可能 可能
a 成功(新規作成) 成功 不可 可能(末尾に追記)
a+ 成功(新規作成) 成功 可能 可能(末尾に追記)
x 成功(新規作成) エラー 不可 可能
x+ 成功(新規作成) エラー 可能 可能
「r」「w」は、開いたファイルの先頭からの読み出し・書き込みになる。
「a」は、既存ファイルを開いた場合にファイルの末尾からの追記になる。
モードに「b」を追加して「r+b」「wb」のように指定するとバイナリモードで開く。デフォルトはテキストモードになる。
バイナリモードではファイルのデータをバイト列としてバイト単位で読み書きする。
2025.04.26
テキストファイルへ文字列を書き込む write()
f = open("test.txt", "w")
data = "ABCDEF\nあいうえお\n123456789"
f.write(data)
f.close()
test.txt
ABCDEF
あいうえお
123456789
write()メソッドは、ファイルへ文字列を書き込む。引数に与える文字列がファイルに書き込まれる。
ファイルオブジェクト.write(文字列)

複数文字列の書き込み

f = open("test.txt", "w")
lines = ["GHIJKLM\n", "かきくけこ\n", "09876543\n"]
f.writelines(lines)
f.close()
test.txt
GHIJKLM
かきくけこ
09876543
writelines()メソッドは、文字列のリストの要素を順番にファイルに書き込む。
各文字列は自動的に改行されない。
ファイルオブジェクト.writelines(文字列のリスト)
2025.04.26
テキストファイルを読み込む
test.txt
GHIJKLM
かきくけこ
09876543
f = open("test.txt", "r")
txt = f.read(10)
f.close()
print(txt)
GHIJKLM
かき
read()メソッドは、テキストファイルから文字列を読み出す。
引数には読み込む文字数を指定できる。改行も1文字として読み出す。文字数を省略した場合はファイル全体を読み出す。
文字列 = ファイルオブジェクト.read(文字数)

行の読み出し

f = open("test.txt", "r")
ln = f.readline()
while ln:
    print(ln, end="")
    ln = f.readline()
f.close()
GHIJKLM
かきくけこ
09876543
readline()メソッドは、テキストファイルを行単位に読み出す。
readline()を繰り返し呼び出すと、次の行を読み出す。戻り値は、末尾に改行が含まれた状態の行の文字列が返る。テキストファイルの終端に達したときは、空文字「""」が返る。
文字列 = ファイルオブジェクト.readline()

複数行の読み出し

f = open("test.txt", "r")
lines = f.readlines()
f.close()
for ln in lines:
    print(ln)
GHIJKLM
かきくけこ
09876543
readlines()メソッドは、テキストファイルを読み出し、行単位でリストに格納する。
リストの要素の文字列の末尾には改行文字が含まれる。
文字列のリスト = ファイルオブジェクト.readlines()
2025.04.26
バイナリファイルを読み書きする
f = open("test.bin", "wb")
f.write(b"\x01\x02\x03\x04\x05")
f.close()

f = open("test.bin", "rb")
bin = f.read()
print(bin)
f.close()
b'\x01\x02\x03\x04\x05'
open()に指定するモードに"b"を付けた場合、バイナリファイルへの操作になる。
バイナリファイルへの書き込みと読み出しは、write()とread()メソッドを使う。バイナリモードでは、書き込むデータにバイト列を与え、読み出す長さの単位はバイト数になる。
ファイルオブジェクト.write(バイト列)
バイト列 = ファイルオブジェクト.read(バイト数)
2025.04.26
バッファの強制書き込み flush()
f.write("ABCDEFG")
f.flush()
f.close()
flush()メソッドは、物理ディスクへのバッファの書き込みを強制する。
OSがタイミング調整している物理ファイルへの書き出しを即時に行わせる。
ファイルオブジェクト.flush()
2025.04.26
ファイルのオフセット取得とオフセット移動 seek() tell()
test.bin
b'\x01\x02\x03\x04\x05'
f = open("test.bin", "rb")
f.seek(3)
bin = f.read(2)
print(f.tell(), bin)
f.seek(2, 0)
bin = f.read(2)
print(f.tell(), bin)
f.close()
5 b'\x04\x05'
4 b'\x03\x04'
tell()メソッドは、ファイル中の次に読み出す位置(ファイルの先頭を0とするオフセット)を返る。
seek()メソッドは、次に読み出す位置、または書き込む位置を移動して、ファイルの中をランダムにアクセスする。
オフセット = ファイルオブジェクト.tell()
ファイルオブジェクト.seek(移動オフセット, 基準位置)
基準位置 = 0:ファイル先頭から、1:現在位置から、2:ファイル終端から
2025.04.26
with構文
with open("test.txt", "w+") as f:
    f.write("ABCDEF\n")
    f.write("あいうえお\n123456789")
    f.seek(2, 0)
    print(f.read(3))
CDE
with構文により、ファイルオブジェクトを閉じるclose()メソッドの呼び出しを省略できる。
with構文ブロックの中で、ファイルオブジェクトのメソッドによるファイル操作を行う。
ブロックから出るときに、自動的にファイルは閉じられる。
ブロックの中で、ファイルアクセス関係のエラーで例外が発生したときも自動的に閉じられる。open()とclose()で発生し得る例外を完璧にtry~exceptで実装するとたいへん複雑になるので、with構文の利用は有意である。
with open(ファイルパス, モード) as ファイルオブジェクト:
    ファイルの読み書きなどの処理
    ...
with構文は「コンテキストマネージャー」と呼ばれるしくみによって実装しており、ファイル以外にも対応するクラスがある。