Pythonの制御構造としてif/while/for文がある。switch文はない。以下に構文を示す。C言語と同様に、while/for文内ではbreak文で一番内側のループを終了、continue文で次の反復を開始できる。また、while文とfor文にもelse節があるが、これはループ内でbreak文が実行されなかった場合にループ終了時に実行される(途中でループを終了しないときに限って、最後に何らかの処理を付加したい場合に使用できる)。
# if文
if 条件式:
ブロック
[elif 条件式: # elif節は省略/ネスト可能
ブロック]
[else: # else節は省略可能
ブロック]
# while文
while 条件式:
ブロック
[else: # else節は省略可能
ブロック]
# for文
for 変数名 in 反復可能オブジェクト/イテレータ:
ブロック
[else: # else節は省略可能
ブロック]
以下に例を示す。
for n in range(3):
for m in range(5):
if m == 3:
continue
print("n: " + str(n) + ", m: " + str(m))
# 出力結果:
# n: 0, m: 0
# n: 0, m: 1
# n: 0, m: 2
# n: 0, m: 4
# n: 1, m: 0
# n: 1, m: 1
# …… 省略 ……
b = b'abcdefg' # bはbytes型(バイトストリーム)
l = len(b)
c = 0
while c < l:
print(b[c])
c += 1
# 出力結果:
# 97
# 98
# 99
# …… 省略 ……
Pythonの関数には名前付き関数/ラムダ式(無名関数)/ジェネレーター関数(ジェネレーター式)がある(Python 3.5以降では「コルーチン」もあるが、本稿では省略する)。
これらの構文を以下に示す。
# 関数定義
def 関数名([パラメーターリスト]):
ブロック
# 無名関数定義
f = lambda [パラメーターリスト]: 式 # 無名関数を定義して、それを変数fに束縛
f(...) # 無名関数呼び出し
# ジェネレーター
def ジェネレーター関数名([パラメーターリスト]):
ブロック
# ジェネレーター式
g = 式 for 変数 in 反復可能オブジェクト
ラムダ式は単一の式のみからなる無名関数を定義する(小規模な処理を、他の関数の引数として渡す場合などに使用する)。ジェネレーター関数/ジェネレーター式は呼び出されるとジェネレーターオブジェクトを返送する。ジェネレーターオブジェクトは、その実行コンテキストを記憶しており、return文ではなくyield文を使用して、呼び出し元に何らかの値を返送する。その後、制御がジェネレーターオブジェクトに戻ると、直前の状態から実行を継続する。Python 3.3以降では「yield from イテレーター」として、別のイテレーターに処理を委譲できる。
以下に例を示す。
def even(n): # 関数定義
return not n % 2
l = list(range(5))
# filter関数の引数に関数を渡す(偶数のみをリストから取得)
l2 = list(filter(even, l))
print(l2) # 出力結果: [0, 2, 4]
# 同じことをラムダ式を使用して行う
l3 = list(filter(lambda x: not x % 2, l))
print(l3) # 出力結果: [0, 2, 4]
# ジェネレーター関数定義
def gen(n):
for m in range(n):
yield m # return文ではなくyield文で呼び出し側に値を返送する
for num in gen(3): # ジェネレーター関数の利用
print(num)
# 出力結果:
# 0
# 1
# 2
# ジェネレーター式
for num in (i + 1 for i in range(3)):
print(num)
# 出力結果:
# 1
# 2
# 3
# ラムダ式とジェネレーター式の組み合わせ
g = lambda x: (i + 1 for i in range(x))
h = g(3)
for num in h:
print(num)
# 出力結果:
# 1
# 2
# 3
# 関数nextにジェネレーターを渡して、反復を行う
h = g(4)
print(next(h)) # 出力結果: 1
# ジェネレーターgen1に処理を委譲
def gen1():
yield 1
yield 2
def gen2():
yield from gen1()
yield 3
for num in gen2():
print(num)
# 出力結果:
# 1
# 2
# 3
# rangeオブジェクトに処理を委譲
def gen3():
yield from range(3)
for num in gen3():
print(num)
# 出力結果:
# 0
# 1
# 2
関数には可変数個の引数やキーワード引数を渡せる。これらについては「Pythonの関数、超速入門」を参照されたい。
Pythonの例外処理には、他の言語と同様なtry〜except〜else〜finally形式の構文と例外発生時にはこれを処理せずにクリーンアップのみを行うtry〜finally形式の構文がある。以下に構文を示す。
# 例外処理その1
try:
ブロック
except [例外型を表す式 [as 変数名]]: # except節はネスト可能
ブロック
[...
except: # 何も指定しないexcept節は最後に記述。他の例外全てを捕捉する
ブロック]
[else: # try節が末尾まで実行されたときに実行される。else節は省略可能
ブロック]
[finally:
ブロック] # 例外の有無に関係なく最後に実行される。finally節は省略可能
# 例外処理その2
try:
ブロック
finally:
ブロック
「例外処理その1」のelse節はtry節で例外が発生しなかった場合に実行される。finally節は例外の有無に関係なくクリーンアップ処理を行う。except節の「例外型を表す式」の評価結果は何らかの例外型となる必要がある。例えば、1つのexcept節で複数の例外を捕捉するには、タプルを使って「except (OverflowError, ZeroDivisionError) as exc:」のように指定する。
また、except節は「例外型を表す式」に記述された例外型と「互換な例外」(=その例外型もしくはその派生クラス)を捕捉する。このため、この式に並べる例外の順序には気を付ける必要がある。また、何も指定しないexcept節は最後に記述する必要がある(それまでの「例外型を表す式」に該当しない全ての例外が捕捉される)。
try:
1 / 0 # 0除算
except (ZeroDivisionError, OverflowError) as exc: # タプルで複数例外を捕捉
print(exc)
except: # その他の例外を捕捉
print("trap Exception")
else: # この例ではelse節は実行されない
print("else")
finally: # クリーンアップ処理
print("finally")
# 出力結果:
# division by zero
# finally
例外を送出するコードは次のようになる。
# 例外の送出
raise [例外オブジェクト1 [from 例外オブジェクト2]]
例外が連鎖した場合に、例外を再送出する場合などには、「from 例外オブジェクト」を指定して、その例外の原因となった例外を指定できる。
最後にクラスとモジュールについて見ておこう。
Copyright© Digital Advantage Corp. All Rights Reserved.