calendarcodediamondfacebookfingerglobalgoogleplushatenahomepagetopplainpocketrssservicetwitterwordpresshome2searchfoldernext-arrowback-arrowfirst-arrowlast-arrow

Python : 関数の基本操作編(デフォルト値、キーワード引数、可変長引数、関数内関数、ラムダ など)

関数は処理をまとめた再利用可能なコードである。関数は他のコードから切り離され、名前を付けられたコードである。

エンジニア速報は Twitter の@commteで 1 日 5 回配信しています。

Sponsored Link

目次

関数のポイント

  • Python では関数もオブジェクト
  • 関数を定義するには def と入力する
  • 関数名の先頭は英字か_ を使う
>>> def h(): ... print('hello') ... >>> type(h) <class 'function'>

Python の関数には、3 つの特徴がある。

  • 名前を持つ
  • 手続きの流れを含む
  • 返り値(return で定義)

関数の基本形

def hoge(): print('hello') # 関数呼び出し hoge() # hello

関数名には小文字とアンダースコアを使う。引数のない呼び出しはエラーになる。

実引数と仮引数

関数定義時に使う引数を仮引数と呼び、関数呼び出し時に渡す引数を実引数と呼ぶ。関数の外からは実引数、関数の中では仮引数。

実引数を渡して関数を呼び出すとき、それらの値は関数内の対応する仮引数にコピーされる。

実引数が不足したり多かったりするとエラーになる。変数に関数を代入することもできる。

def w(): print('word') h = w() # 変数に関数を代入 h # word
def h(name): print('hello ' + name) h('john') # hello john

仮引数にデフォルト値

関数の呼び出しには、デフォルト値を持たせられる。引数名=デフォルト値 といったように指定する。

def h(w='word'): print(w) h() # word

引数を渡すと、その値が利用される。

def h(w='word'): print(w) h('change') # change

キーワード引数

キーワード引数は関数の呼び出しで、仮引数名を指定して渡す実引数である。キーワード引数(実引数にセット) 呼び出し時の順番は呼び出し結果に影響しない。

def h(a, b): return a h(b=1, a=2) # キーワード引数 # 2

return 文

return 文を使うと、関数の戻り値を指定できる。return 文が実行されると、そこで処理が終了する。

def i(plus): return plus + 1 i(2) # 3
def h(n = 'guest'): if n == 'guest': return '名前を教えてください' h() # '名前を教えてください'

複数の引数をセットできる。以下、BMI を計算させてみる。

def bmi(h,w): return w / (h/100) ** 2 bmi(174, 62) # 20.478266613819528

return がない場合

return 文がない場合は None が返される。return 文が実行されない関数は保守性が低くなるので、常に return 文が実行されるように戻り値を書くべきである。

def no_r(): pass print(no_r()) # None

可変長引数

可変長引数は、数が決まっていない引数を渡す方法である。関数の引数が任意の個数となっている。 可変長の引数を受け取る関数は、仮引数名に * アスタリスクをつけて定義する。 仮引数に割り当てられなかった位置引数をタプルで受け取る。

# 慣例として *args と記述することが多い。 def h(*args): for i in args: print(i) h('one', 'two', 'three') # one # two # three

可変長のキーワード引数

アスタリスクを 2 つ使うことで、キーワード引数を 1 つの辞書にまとめることができる。可変長のキーワード引数を受け取る関数は、仮引数名にアスタリスクを 2 つ付けると定義できる。

# 慣例として **kwargs と記述することが多い。 def h(**kwargs): print(kwargs) h(a=10, b=20, c=30) # {'a': 10, 'b': 20, 'c': 30}

キーワード専用引数

引数に単独の * を付けた場合、* 以降の引数は、キーワード引数という形でしか渡せない。

def h(a, *, b): print(f'{a} {b}') h(1, b=2) # 1 2

関数内関数

関数の中に関数を入れることも可能である。外側の関数から内側の関数を呼び出す。

関数内関数はクロージャ(ほかの関数によって動的に生成される関数)として機能し、自分の外で作られた変数の値を変更できる。

def out(a, b): print('関数を呼び出します') def inner(c, d): return c + d return inner(a, b) out(2, 3) # 関数を呼び出します # 5

ラムダ関数

ラムダ関数は、一行で表現される無名関数である。無名関数とは、関数が必要なときにその場で定義する使い捨て関数である。無名が故に「関数名を考える必要がない」というメリットもある。

どんなときに使われるのかというと、関数を「引数」として受け取る関数を呼び出すときなど。

ラムダは 0 個以上のカンマ区切りの実引数を取り、後ろにコロンをつけ、関数定義をする。lambda では丸括弧を使わない。

無名関数は、関数の引数として関数オブジェクトを渡すときに利用される。式はそのまま返されるので、return 文は不要である。

lambda 引数1, 引数2 : 戻り値
b = lambda a : a + 1 b(2) # 3 b = lambda a, b : a + b b(1,2) # 3

関数を引数として呼び出す。

n = ['Python', 'Rust', 'Go'] f = filter(lambda i: len(i) == 4, n) list(f) # ['Rust']

ジェネレーター関数

return を yield に変えれば、複数の値を一つずつ作り出すジェネレーターになる。ジェネレーター関数を使うことにより、yeild のところまで処理を進め一旦停止する。そして任意のタイミングで処理を再開することができる。

参考 : yield を使う関数をジェネレーター関数、内包表記を使うものをジェネレーター式という

次のコードは、next 関数が呼ばれるたびに、関数の中の処理が次の yield まで進んでいることを示している。値がなくなると例外 StopIteration が返る。

def g(n): while n: yield n n -= 2 a = g(100) next(a) # 100 next(a) # 98 next(a) # 96

デコレータ

ソースコードを書き換えずに、既存の関数に変更を加えたいことがある。デコレータは、既存関数に対してコードの変更なしに処理を追加する関数である。

参考 : デコレータは既存の関数に機能を追加する関数

def a(x): def new_a(): print('before') x() print('after') return new_a @a def b(): print('middle') b() # before # middle # after

型ヒント

関数には、アノテーション(タグ付け)を用いて型ヒント(関数の引数と戻り値に型情報を付ける機能)を追加できる。しかし、実行時に型チェックが行われるわけではない。あくまでも注釈であり、コードの保守性を向上させるために付与するのである。

使い方

  • :の横に型を指定
  • -> の横は返り値の型を指定
def w(a:int) -> int: return a w(3) # 3
def greeting(name: str) -> str: return 'Hello ' + name

再帰

関数が自分自身を呼び出すことを再帰という。再帰はリストのネストなど、平坦ではないデータを処理するときに役立つ。

def flat(x): for i in x: if isinstance(i, list): for i_in in flat(i): yield i_in else: yield i x = [1, 2, [3, 4, 5], [6, [7, 8, 9]]] list(flat(x)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Python おすすめ本

スポンサード リンク

Comments

Leave a Comment

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください