Python 3で関数を定義する方法

紹介

A function is a block of instructions that performs an action and, once defined, can be reused. Functions make code more modular, allowing you to use the same code over and over again.

Pythonには、おそらくおなじみのいくつかの組み込み関数があります。

  • print()はオブジェクトを端末に出力します。
  • int()は文字列または数値データ型を整数データ型に変換します。
  • len()はオブジェクトの長さを返します。

関数名には括弧が含まれ、パラメータを含むことがあります。

このチュートリアルでは、コーディングプロジェクトで使用するための独自の関数を定義する方法について説明します。

前提条件

Python 3がインストールされており、コンピューターまたはサーバーにプログラミング環境が設定されている必要があります。プログラミング環境が設定されていない場合は、オペレーティングシステム(Ubuntu、CentOS、Debianなど)に適したローカルプログラミング環境またはサーバー上のプログラミング環境のインストールとセットアップガイドを参照してください。

関数の定義

古典的な「こんにちは、世界!」プログラムを関数に変換してみましょう。

まず、お好みのテキストエディタで新しいテキストファイルを作成し、プログラムをhello.pyと呼びます。その後、関数を定義します。

A function is defined by using the def keyword, followed by a name of your choosing, followed by a set of parentheses which hold any parameters the function will take (they can be empty), and ending with a colon.

情報: このチュートリアルの例コードに従うには、ローカルシステムでPythonインタラクティブシェルを開き、python3コマンドを実行します。その後、>>>プロンプトの後に例を追加、コピー、または編集できます。

この場合、hello()という名前の関数を定義します:

hello.py
def hello():

これは関数を作成するための初期のステートメントを設定します。

ここから、関数が何をするかの指示を提供するために、4スペースのインデントを持つ2行目を追加します。この場合、コンソールにHello, World!を出力します:

hello.py
def hello():
    print("Hello, World!")

関数はすでに完全に定義されていますが、この時点でプログラムを実行すると何も起こりません。なぜなら、関数を呼び出していないからです。

したがって、定義された関数ブロックの外で、hello()を使用して関数を呼び出します:

hello.py
def hello():
    print("Hello, World!")

hello()

さて、プログラムを実行しましょう:

  1. python hello.py

次の出力が表示されるはずです:

Output
Hello, World!

関数は、上記で定義したhello()関数よりも複雑になる可能性があります。たとえば、forループ条件文などを、関数ブロック内で使用することができます。

たとえば、以下で定義された関数は、name変数の入力に母音が含まれているかどうかを確認する条件文を使用し、name文字列内の文字を反復処理するためにforループを使用しています。

names.py
# 関数names()を定義
def names():
    # 入力を使用してname変数を設定
    name = str(input('Enter your name: '))
    # nameに母音が含まれているかどうかを確認
    if set('aeiou').intersection(name.lower()):
        print('Your name contains a vowel.')
    else:
        print('Your name does not contain a vowel.')

    # nameを反復処理
    for letter in name:
        print(letter)

# 関数を呼び出す
names()

上記で定義したnames()関数は、条件文とforループを設定し、コードが関数定義内でどのように組織されるかを示しています。ただし、プログラムの意図やコードの設定方法によっては、条件文とforループを2つの別々の関数として定義したい場合があります。

プログラム内で関数を定義することで、コードをモジュール化して再利用可能にし、同じ関数を繰り返し呼び出すことができます。

パラメーターを使用する

これまで、引数を取らない空の括弧を持つ関数を見てきましたが、関数定義内の括弧内にパラメーターを定義することができます。

A parameter is a named entity in a function definition, specifying an argument that the function can accept.

パラメーターxy、およびzを取る小さなプログラムを作成しましょう。パラメーターを異なる構成で合計する関数を作成します。これらの合計は、関数によって出力されます。その後、関数を呼び出して関数に数字を渡します。

add_numbers.py
def add_numbers(x, y, z):
    a = x + y
    b = x + z
    c = y + z
    print(a, b, c)

add_numbers(1, 2, 3)

私たちはxパラメーターに1yパラメーターに2zパラメーターに3を渡しました。これらの値は、与えられた順序で各パラメーターに対応します。

プログラムは、基本的に、パラメーターに渡した値に基づいて次のような数学を行っています:

a = 1 + 2
b = 1 + 3
c = 2 + 3

関数はまた、ab、およびcを出力します。上記の数学に基づくと、a3に等しくなり、b4になり、c5になると予想されます。プログラムを実行しましょう:

  1. python add_numbers.py
Output
3 4 5

add_numbers()関数に123をパラメーターとして渡すと、期待される出力が得られます。

パラメータは、通常、関数定義内の変数として定義される引数です。メソッドを実行する際に、引数を関数に渡して値を割り当てることができます。

キーワード引数

順番に引数を呼び出すだけでなく、関数呼び出しでキーワード引数を使用することができます。その場合、呼び出し元がパラメータ名で引数を識別します。

キーワード引数を使用すると、Python インタープリターは指定されたキーワードを使用して値をパラメータにマッチングするため、順不同でパラメータを使用できます。

ユーザーのプロファイル情報を表示する関数を作成しましょう。関数には、username(文字列として意図されたもの)とfollowers(整数として意図されたもの)の形式でパラメータを渡します。

profile.py
# パラメータを持つ関数を定義
def profile_info(username, followers):
    print("Username: " + username)
    print("Followers: " + str(followers))

関数定義文の中で、usernamefollowersprofile_info()関数の括弧内に含まれています。関数のブロックは、2つのパラメータを使用して、ユーザーに関する情報を文字列として出力します。

さて、この関数を呼び出してパラメータを割り当てることができます:

profile.py
def profile_info(username, followers):
    print("Username: " + username)
    print("Followers: " + str(followers))

# 上記のようにパラメータを割り当てて関数を呼び出す
profile_info("sammyshark", 945)

# キーワード引数を使用して関数を呼び出す
profile_info(username="AlexAnglerfish", followers=342)

最初の関数呼び出しでは、情報をsammysharkというユーザー名とフォロワーが945で満たし、2番目の関数呼び出しではキーワード引数を使用し、引数変数に値を割り当てました。

プログラムを実行しましょう:

  1. python profile.py
Output
Username: sammyshark Followers: 945 Username: AlexAnglerfish Followers: 342

出力には、両方のユーザーのユーザー名とフォロワーの数が表示されます。

これにより、パラメーターの順序を変更することもできます。次の例では、異なる呼び出しで同じプログラムを使用しています:

profile.py
def profile_info(username, followers):
    print("Username: " + username)
    print("Followers: " + str(followers))

# パラメーターの順序を変更
profile_info(followers=820, username="cameron-catfish")

プログラムを再度python profile.pyコマンドで実行すると、次の出力が表示されます:

Output
Username: cameron-catfish Followers: 820

関数定義がprint()ステートメントの順序を維持しているため、キーワード引数を使用する場合は、関数呼び出しにそれらをどの順序で渡しても問題ありません。

デフォルト引数値

1つまたは両方のパラメーターにデフォルト値を指定することもできます。 followersパラメーターのデフォルト値を1に設定してみましょう:

profile.py
def profile_info(username, followers=1):
    print("Username: " + username)
    print("Followers: " + str(followers))

これで、ユーザー名関数のみが割り当てられた状態で関数を実行でき、フォロワーの数は自動的にデフォルト値1になります。必要に応じてフォロワーの数を変更することもできます。

profile.py
def profile_info(username, followers=1):
    print("Username: " + username)
    print("Followers: " + str(followers))

profile_info(username="JOctopus")
profile_info(username="sammyshark", followers=945)

python profile.pyコマンドでプログラムを実行すると、次の出力が表示されます:

Output
Username: JOctopus Followers: 1 Username: sammyshark Followers: 945

デフォルトの値を持つパラメーターを提供すると、既にデフォルト値を持つ引数の値を定義する必要がなくなります。

値の返却

関数にパラメーター値を渡すことができ、関数はまた値を生成することもできます。

A function can produce a value with the return statement, which will exit a function and optionally pass an expression back to the caller. If you use a return statement with no arguments, the function will return None.

これまで、関数内でprint()文を使用してきましたが、代わりにreturn文を使用するプログラムを作成しましょう。

square.pyという新しいテキストファイルを作成し、パラメーターxを2乗して変数yを返すプログラムを作成します。square()関数を3で呼び出して形成されるresult変数を出力します。

square.py
def square(x):
    y = x ** 2
    return y

result = square(3)
print(result)

プログラムを実行して出力を受け取ることができます:

  1. python square.py
Output
9

整数9が出力され、Pythonに3の2乗を見つけるように求めた結果と一致します。

return文の動作をさらに理解するために、プログラム内のreturn文をコメントアウトしてみましょう:

square.py
def square(x):
    y = x ** 2
    # return y

result = square(3)
print(result)

さて、プログラムを再度実行してみましょう:

  1. python square.py
Output
None

ここでreturn文を使用しない場合、プログラムは値を返すことができないため、値はデフォルトでNoneになります。

別の例として、上記のadd_numbers.pyプログラムで、print()ステートメントをreturnステートメントに置き換えることができます。

add_numbers.py
def add_numbers(x, y, z):
    a = x + y
    b = x + z
    c = y + z
    return a, b, c

sums = add_numbers(1, 2, 3)
print(sums)

関数の外で、変数sumsを関数に123を渡した結果と同じものに設定しました。その後、sums変数の出力を呼び出しました。

今、returnステートメントを持つプログラムを実行しましょう:

  1. python add_numbers.py
Output
(3, 4, 5)

関数内のprint()ステートメントを使用して以前に受け取ったように、出力として345の同じ数字を受け取ります。今回はタプルとして配信されます。なぜなら、returnステートメントの式リストに少なくとも1つのカンマがあるからです。

関数はreturnステートメントに達したときにすぐに終了します。値を返しているかどうかに関係なく。

return_loop.py
def loop_five():
    for x in range(0, 25):
        print(x)
        if x == 5:
            # x == 5で関数を停止
            return
    print("This line will not execute.")

loop_five()

forループ内でreturnステートメントを使用すると、関数が終了するため、ループの外にある行は実行されません。その代わりにbreakステートメントを使用した場合、その時点でのみループが終了し、最後のprint()行が実行されます。

returnステートメントは、関数から退出し、パラメーターを指定して発行された場合に値を返す場合があります。

main()を関数として使用する

Pythonでは、プログラムの最後に関数を呼び出して実行することができます(上記の例で行ったように)。しかし、C++やJavaなどの多くのプログラミング言語では、実行するためにmain関数が必要です。 main()関数を含めることは必須ではありませんが、Pythonプログラムを論理的な方法で構造化し、プログラムの最も重要なコンポーネントを1つの関数にまとめることができます。また、Python以外のプログラマーにとってプログラムを読みやすくすることもできます。

まず、上記のhello.pyプログラムにmain()関数を追加します。 hello()関数を保持し、main()関数を定義します:

hello.py
def hello():
    print("Hello, World!")

def main():

main()関数内で、main()関数にいることを知らせるprint()ステートメントを含めます。さらに、main()関数内でhello()関数を呼び出します:

hello.py
def hello():
    print("Hello, World!")


def main():
    print("This is the main function")
    hello()

最後に、プログラムの最後でmain()関数を呼び出します:

hello.py
def hello():
    print("Hello, World!")

def main():
    print("This is the main function.")
    hello()

main()

この時点で、プログラムを実行できます:

  1. python hello.py

以下の出力が表示されます:

Output
This is the main function. Hello, World!

hello() 関数を main() 内で呼び出し、その後に main() を呼び出したため、Hello, World! テキストは、メイン関数内にあると示す文字列の後に一度だけ表示されます。

次に、複数の関数を扱う予定なので、グローバル変数とローカル変数の変数スコープを復習する価値があります。関数ブロック内で変数を定義すると、その変数はその関数内でのみ使用できます。関数間で変数を使用したい場合は、グローバル変数を宣言する方が良いでしょう。

Pythonでは、'__main__' はトップレベルのコードが実行されるスコープの名前です。プログラムが標準入力、スクリプト、または対話型プロンプトから実行されると、その __name__'__main__' に設定されます。

このため、次の構文を使用する慣習があります:

if __name__ == '__main__':
    # ここがメインプログラムで実行されるコードです

これにより、プログラムファイルを次のように使用できます:

  • メインプログラムとして使用し、if 文の後に続くものを実行する
  • モジュールとして使用し、if 文の後に続くものを実行しない

この文に含まれていないコードは、実行時に実行されます。プログラムファイルをモジュールとして使用している場合、この文に含まれていないコードも、二次ファイルを実行する際にインポートされます。

上記のnames.pyプログラムを拡張し、more_names.pyという新しいファイルを作成します。このプログラムでは、グローバル変数を宣言し、元のnames()関数を変更して、手順が2つの独立した関数になるようにします。

最初の関数has_vowel()は、name文字列に母音が含まれているかどうかを確認します。

2番目の関数print_letters()は、name文字列の各文字を印刷します。

more_names.py
# すべての関数で使用するためのグローバル変数名を宣言
name = str(input('Enter your name: '))


# 名前に母音が含まれているかどうかを確認する関数を定義
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Your name contains a vowel.')
    else:
        print('Your name does not contain a vowel.')


# 名前文字列内の文字を反復処理する
def print_letters():
    for letter in name:
        print(letter)

このセットアップで、has_vowel()およびprint_letters()関数の呼び出しを含むmain()関数を定義しましょう。

more_names.py
# すべての関数で使用するためのグローバル変数名を宣言
name = str(input('Enter your name: '))


# 名前に母音が含まれているかどうかを確認する関数を定義
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Your name contains a vowel.')
    else:
        print('Your name does not contain a vowel.')


# 名前文字列内の文字を反復処理する
def print_letters():
    for letter in name:
        print(letter)


# 他の関数を呼び出すmainメソッドを定義する
def main():
    has_vowel()
    print_letters()

最後に、ファイルの最下部にif __name__ == '__main__':構文を追加します。私たちの目的上、すべての機能をmain()関数に配置したので、このif文の後にmain()関数を呼び出します。

more_names.py
#すべての関数で使用するためのグローバル変数名を宣言します
name = str(input('Enter your name: '))


#名前に母音が含まれているかどうかをチェックする関数を定義します
def has_vowel():
    if set('aeiou').intersection(name.lower()):
        print('Your name contains a vowel.')
    else:
        print('Your name does not contain a vowel.')


#名前文字列の文字を繰り返します
def print_letters():
    for letter in name:
        print(letter)


#他の関数を呼び出すmainメソッドを定義します
def main():
    has_vowel()
    print_letters()


#main()関数を実行します
if __name__ == '__main__':
    main()

これでプログラムを実行できます:

  1. python more_names.py

プログラムはnames.pyプログラムと同じ出力を表示しますが、ここではコードがより整理されており、変更せずにモジュール化して使用できます。

もしmain()関数を宣言したくなかった場合は、代わりに以下のようにプログラムを終了することもできます:

more_names.py
...
if __name__ == '__main__':
    has_vowel()
    print_letters()

main()を関数として使用し、if __name__ == '__main__':文を使用すると、コードを論理的な方法で整理し、より読みやすく、モジュール化することができます。

結論

関数は、プログラム内でアクションを実行する命令のコードブロックであり、コードの再利用性とモジュール化を支援します。

コードをよりモジュール化する方法について詳しく学ぶには、Python 3でモジュールを書く方法のガイドを読んでみてください。

Source:
https://www.digitalocean.com/community/tutorials/how-to-define-functions-in-python-3