特集
» 2016年10月28日 05時00分 公開

TensorFlowやChainerに興味があるけど、Python未経験の技術者が最低限知っておいた方がいい基礎文法まとめ特集:タイニーレファレンス(5/6 ページ)

[かわさきしんじ,Insider.NET編集部]

制御構造

 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# 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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。