TensorFlowやChainerに興味があるけど、Python未経験の技術者が最低限知っておいた方がいい基礎文法まとめ:特集:タイニーレファレンス(5/6 ページ)
Python 3の基本となる構文要素や、データ型の使い方、関数とクラスの定義方法を構文やサンプルコード多めでギュッと濃縮。
制御構造
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.
