Pythonにおけるdef文は関数を定義するキーワードです。
関数とはある特定のタスクや計算を実行する一連の命令をまとめたもの。必要な時に何度でも呼び出すことができるため、同じコードを何度も書くことなく、一度定義した関数を何度でも再利用できます。こうした再利用性は、コードの効率性と可読性を大いに向上させます。
参考 Pythonの特徴
関数を定義するには、Pythonではdef
キーワードを使用します。
このページでは、Pythonの関数定義とその使い方について詳しく解説します。初心者から上級者まで、Pythonの関数をより深く理解し、その力をフルに発揮するための手引きとなることを目指します。
Pythonエンジニアを目指す方や、Pythonをマスターしようとしている方であれば知らないと恥ずかしい超・基本知識です。是非最後までご覧ください。
【前提】関数とは何か?
まずは基本から始めましょう。前提となる「関数」とは何か?の解説から始めます。そんなの分かっているよ・・という方は読み飛ばしでOKです。
関数とは、ある特定のタスクや計算を実行する一連の命令をまとめたものです。プログラム全体を一つの大きな塊として扱うのではなく、小さな部品(関数)に分割することで、プログラムの構造を理解しやすくするとともに、再利用性と保守性を高めることができます。
プログラムをコーディングしていくと、同じような処理を複数回実行する必要がある場合あります。例えば、入力された値のチェックや、毎回同じように行う必要がある計算式など。
このような場合に何度も繰り返す必要があるような処理を予め部品化しておいて、何度も呼び出す形で利用することができれば便利です。これが関数のメリットです。
また、関数をうまく使いこなすことができるようになれば、コード全体の「構造化」が図れ効率的なプログラミングが可能となり、完成するプログラミングも全体としてかっこいい出来上がりになります。
もちろん、関数を使わなくてもプログラミング自体は可能ですが、事実上関数なしで一つの機能を作り上げるのは事実上不可能です。
Python def:関数の定義と実行
関数(def)は大きく「①定義」と「②実行」で分けて考えると直感的に理解しやすくなります。
まずは、「①定義」方法―。関数を作る方法から解説します。
Python関数の定義:def
Pythonで関数を定義するためには、def
というキーワードを使用します。その後に関数名と引数を記述します。
def 関数名(引数1, 引数2, ..., 引数n): # この部分は関数の本体です。ここに実行したい処理を書きます。 # 'return'を使って、関数の戻り値を指定します。 return 戻り値
ここで、「関数名
」は関数の名前、「引数1引数2, ..., 引数n
」は関数に渡すパラメータ(任意)を表します。関数の本体では、具体的な処理を記述し、return
を用いて関数の結果(戻り値)を返します。
例えば、2つの数値の和を計算する関数は次のように定義することができます。
def add(a, b): # aとbの和を計算します。 result = a + b # 計算結果を返します。 return result
また、Pythonではインデント(通常はスペース4つまたはタブ1つ)が非常に重要な役割を果たしますが、関数を定義する際にもそれは同じ。
サンプル1 正しいインデント
def add(a, b): # ここからインデントが始まります。 result = a + b return result # ここでインデントが終わります。
サンプル2 不適切なインデント(エラーが発生します)
def add(a, b): # ここではインデントが必要です。 result = a + b return result
Pythonではインデントがコードの構造を決定するため、正確なインデントは非常に重要です。特に、関数定義では、関数の本体を適切にインデントすることで、その関数がどのコードを実行するのかが明確になります。
Python:関数の命名ルール
関数の名称はなんでもよいという訳ではありません。Pythonの関数を命名する際には以下のルールを順守する必要があります。
以上が基本的なPythonの関数命名規則です。これらのルールを遵守することで、関数名がPythonの構文解析器によって正しく解釈され、また他の開発者にとっても理解しやすいコードになります。
また、厳密なルールではありませんが関数名は理にかなった名前をつけるべし!という点を頭に入れておきましょう。
関数は再利用することを前提としているため、関数名だけで何となくの処理の内容がわかるかどうかは非常に重要なポイントです。
良い例:
def calculate_average(numbers): return sum(numbers) / len(numbers) # この関数を呼び出す print(calculate_average([1, 2, 3, 4, 5])) # 3.0
上記の例では、関数名が「calculate_average」になっており、その関数が何をするのか非常に明確です。この関数名から、我々はこの関数が何らかの数の平均を計算することを推測できます。そして、関数の内部を見るとその推測が正しいことが確認できます。
悪い例:
def do_something(lst): return sum(lst) / len(lst) # この関数を呼び出す print(do_something([1, 2, 3, 4, 5])) # 3.0
一方、上記の例では関数名が「do_something」になっています。この関数名は非常に抽象的であり、この関数が何をするのか全く明らかではありません。その結果、この関数を見た人は関数の内部を詳しく調べなければ、関数の動作を理解することが難しくなります。
関数名はその関数が何をするのかを具体的に示すべき。そのためには、関数名を明確かつ具体的に、そしてその動作を正確に表すように選ぶことが重要です。
Python関数の実行
def文で定義した関数を実行(呼び出し)するための方法を説明します。
Pythonで関数を実行(呼び出し)する基本的な構文は以下の通り。
戻り値 = 関数名(引数1, 引数2, ..., 引数n)
以下に、具体的な関数呼び出しの例を示します。
# 'add'関数の定義 def add(a, b): return a + b # 'add'関数を呼び出し、その結果を'result'変数に格納 result = add(3, 5) # 'result'の値を表示 print(result) # 8
この例では、add
関数に引数3
と5
を渡し、その結果をresult
という変数に格納しています。
まだ少しピンと来ていない方も大丈夫です。
ここから、いくつかサンプルコードを紹介していきますでの、少しずつイメージを掴んでいきましょう。
サンプル1 フィボナッチ数列を生成する関数
フィボナッチ数列は、前の2つの数の和が次の数になる数列です。
def fibonacci(n): result = [] a, b = 0, 1 while len(result) < n: result.append(a) a, b = b, a + b return result # 上記の関数を使って、最初の10個のフィボナッチ数列を表示 print(fibonacci(10)) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
この関数は指定した個数のフィボナッチ数列を生成します。
引数には生成したいフィボナッチ数列の要素数を指定します。数列はリストの形で返され、そのリストはフィボナッチ数列の最初から指定された数の要素を含みます。
サンプル2 与えられたリストを逆順にする関数
def reverse_list(lst): return lst[::-1] # 上記の関数を使って、リストを逆順に表示 print(reverse_list([1, 2, 3, 4, 5])) # [5, 4, 3, 2, 1]
この関数は、引数として与えられたリストを逆順にして返します。リストの要素が数値である場合でも、文字列である場合でも、任意の型の要素を含むリストに対して使用することができます。
サンプル3 文字列がパリンドロームであるか判定する関数
def is_palindrome(s): return s == s[::-1] # 上記の関数を使って、パリンドロームかどうかを判定 print(is_palindrome("radar")) # True print(is_palindrome("python")) # False
この関数は、与えられた文字列がパリンドローム(前から読んでも後ろから読んでも同じになる文字列)であるかどうかを判断します。文字列がパリンドロームである場合、関数はTrueを返し、そうでない場合はFalseを返します。
サンプル4 文字列の中で最も頻繁に出現する文字を返す関数
def most_frequent_char(s): return max(s, key=s.count) # 上記の関数を使って、最も頻繁に出現する文字を表示 print(most_frequent_char("hello world")) # 'l'
この関数は、与えられた文字列の中で最も頻繁に出現する文字を返します。文字列に複数の最も頻繁な文字が含まれる場合、最初に出現するものが返されます。
これらの例を参考に、自分のニーズに合った関数を定義してみてください。関数は、コードの再利用性と可読性を高める強力なツールです。
Python:関数の '引数' と '戻り値'
関数の '引数' と '戻り値' については、プログラミング初心者の方はちょっとだけとっつきにくい箇所でもあるので、この章で詳しく解説します。
Pythonの関数は、ゼロ個以上の引数を取ることができ、これらの引数は関数が行う特定のタスクのための入力データとして機能します。一方、戻り値は、関数が実行した操作の結果を示すもので、関数の呼び出し元に返されます。関数から値を返すためにはreturn
文を使用します。
引数
⇒関数に渡す値―関数へのインプット情報
戻り値
⇒関数から返される値―アウトプット情報
引数・戻り値についても実際のサンプルコードを見ながらイメージを深めましょう。
引数と戻り値:サンプルコード
def add_func(a, b): result = a + b return result sum = add_func(2, 9) print(sum) # 11
ここで、add
という関数は2つの引数a
とb
を受け取り、それらの和を計算し、その結果を戻り値として返します。return
文が呼ばれると、関数は直ちに終了し、指定した値(ここではresult
)が関数の呼び出し元に返されます。
def add_func(a, b): result = a + b return result
2つの引数 "a" "b" を定義します。この "a" と "b" が関数へ渡されます(インプット)。
"a" と "b" を足した値をreturn-戻り値として定義(アウトプット)。
sum = add_func(2, 9) print(sum) # 11
関数へ実際に渡す値を、「(2, 9)」として指定します。引き渡す順番通りに記述すればOK。
戻り値(アウトプット)には「11」が設定されており、この戻り値は直接変数に代入が可能です。
Python関数:引数の指定方法
Pythonの関数では、引数を指定する方法にいくつかのオプションがあります。以下を適切に使用することで、関数の柔軟性と再利用性を向上させることが可能です。
Python関数:位置引数
位置引数は、関数呼び出し時に指定された順序に従って関数に渡される引数です。
def greet(name, greeting): print(f"{greeting}, {name}!") greet("Alice", "Hello")
この例では、greet
関数は2つの位置引数、name
とgreeting
を定義しています。関数を呼び出すときには、"Alice"
が最初の引数name
に、"Hello"
が2番目の引数greeting
に対応します。
位置引数は、その名前が示す通り、引数の順序、つまり位置に基づいています。関数を呼び出す際に引数を渡す順序は、関数の定義時の順序と一致する必要があります。
位置引数の利点は、そのシンプルさと直感性にあります。ただし、大量の引数を持つ関数や、引数の順序を覚えるのが困難な場合、コードの読みやすさや保守性に問題が生じることがあります。また、関数の定義を変更して引数の順序が変わると、その関数を呼び出しているすべてのコードも更新する必要があります。
これらの問題を解決するために、Pythonではキーワード引数やデフォルト引数など、他の種類の引数もサポートしています。
Python関数:キーワード引数
キーワード引数は、関数呼び出し時に引数の名前を明示的に指定して値を渡す方法です。キーワード引数を使用すると、引数の順序を気にせずに関数を呼び出すことが可能になります。
def greet(name, greeting): print(f"{greeting}, {name}!") greet(greeting="Hello", name="Alice")
この例では、greet
関数は2つの引数、name
とgreeting
を定義しています。しかし、関数を呼び出す際には、name=
とgreeting=
を使用して、各引数の名前を明示的に指定して値を渡しています。こうすることで、引数の順序は関係なくなります。
キーワード引数の最大の利点はその柔軟性です。引数の順序を覚えておく必要がないため、関数が多数の引数を取る場合や引数の意味を直感的に理解するのが難しい場合でも、コードが読みやすく、理解しやすくなります。
ただし、キーワード引数を使用する際には注意が必要です。関数定義に存在しない引数名を指定するとエラーが発生します。また、引数を位置引数とキーワード引数の両方で指定するとエラーになります。例えば、以下のコードはエラーになります。
greet("Alice", greeting="Hello") # Raises a TypeError
この例では、greeting
が位置引数としてもキーワード引数としても与えられているため、Pythonはどちらを優先すれば良いか判断できません。このような場合、PythonはTypeError
を発生させ、問題を知らせます。
Python関数:デフォルト引数
デフォルト引数は、関数の引数に対してデフォルトの値を指定する機能です。
つまり、引数に何も渡されなかった場合に設定される値を事前に定義することが可能ということ。
def greet(name, greeting="Hello"): print(f"{greeting}, {name}!") greet("Alice") # Outputs: Hello, Alice!
この例では、greet
関数は引数greeting
にデフォルト値"Hello"
を設定しています。そのため、greet
関数を呼び出す際にgreeting
引数を省略すると、デフォルトの"Hello"
が使用されます。
デフォルト引数は、関数の使用を簡単にし、コードの冗長性を減らすための強力な機能です。多くの場合、関数の引数は特定の一般的な値を持つことがあります。そのような値をデフォルト引数として設定することで、それらの一般的なケースでの関数の使用を簡素化することができます。
デフォルト引数を使用する際にはいくつか注意点があります。1つは、デフォルト引数の値が関数が定義された時点で評価されるという点です。つまり、変更可能なデータ型(リストや辞書など)をデフォルト引数として使用すると、予期しない挙動を引き起こす可能性があります。
もう一つの注意点は、デフォルト引数は常に位置引数とキーワード引数の後に来なければならないという点です。例えば、以下のコードはエラーになります。
def sample(age, name="田中"): print(name,age) sample("10歳") # 引数指定なし sample("20歳","鈴木") # 引数に「鈴木」を指定 # 田中 10歳 # 鈴木 20歳
もし、逆にすると構文エラーが発生します。
def sample(name="田中",age): print(name,age) sample("10歳") # 引数指定なし sample("20歳","鈴木") # 引数に「鈴木」を指定 # SyntaxError: non-default argument follows default argument
Python関数:可変長引数
可変長引数は、任意の数の引数を関数に渡すことを可能にします。
Pythonでは、*args
を使用して任意の数の位置引数を受け取ることができ、**kwargs
を使用して任意の数のキーワード引数を受け取ることができます。
def print_args(*args): for arg in args: print(arg) print_args("Alice", "Bob", "Charlie") # Outputs: Alice, Bob, Charlie def print_kwargs(**kwargs): for key, value in kwargs.items(): print(f"{key} = {value}") print_kwargs(name="Alice", age=25) # Outputs: name = Alice, age = 25
この例では、print_args
関数は任意の数の位置引数を受け取り、それぞれを出力します。同様に、print_kwargs
関数は任意の数のキーワード引数を受け取り、それぞれのキーと値を出力します。
可変長引数は、関数に対して非常に柔軟な引数の渡し方を提供します。これにより、引数の数が固定ではない場合や、関数に渡す引数が動的に変わる可能性がある場合に便利です。
*args
はタプルとして扱われ、**kwargs
は辞書として扱われます。これにより、関数内部ではargs
とkwargs
を通常のタプルや辞書として操作することができるということ。
さらに詳しく知りたい方は > Python関数の可変長引数を詳しく解説
複数の戻り値を設定する方法
Pythonの関数では戻り値を複数個指定することも可能です。
以下のように「,(カンマ)」で複数個の戻り値を指定するだけ。
def get_name(): first_name = "John" last_name = "Doe" return first_name, last_name name = get_name() print(name) # 出力: ('John', 'Doe')
この例では、関数 get_name
は first_name
と last_name
の2つの値を返します。実際には、タプルとして返されます。
Python関数:ローカル変数とグローバル変数
ここまででPythonの関数(def文)に関する基本的な理解はOK。
最後にもう1つだけ合わせて覚えておきたいのが、ローカル変数とグローバル変数についての知識です。
Pythonにおいて、ローカル変数とグローバル変数は、変数のスコープ(有効範囲)に基づいて異なる特性を持ちます。ローカル変数は関数内で定義され、その関数内でのみアクセス可能です。一方、グローバル変数は関数外で定義され、複数の関数やモジュール内のどこからでもアクセス可能です。
ローカル変数
変数を宣言した関数内でのみ有効(利用可能)
グローバル変数
プログラム内のどこでも有効(利用可能)
両者は以下のように変数のスコープが異なるため、頭に入れておかないと思わぬエラーを引き起こすことになります。
a = 1 # グローバル変数 def sample1(): b = 1000 # ローカル変数 print(a) print(b) # NameError: name 'b' is not defined
ローカル変数とグローバル変数の違いについては、下記ページで詳しく解説しておりまので、この機会に合わせて学んでおきましょう。
Python:関数のまとめ
始めてPythonを勉強するのは結構難しいですよね。
でもその悩みを抱えているのは一人じゃありません。全てのPython使いが同じ道を進んできました。
Pythonをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?今すぐ行動したい方は以下の記事をチェック!
読者料典 Python入門:学習カリキュラム ←こちらから!