Python 関数の基本

PythonPythonBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Python 関数を定義して使用する方法を学びます。簡単な例から始めて、徐々に複雑さを増やします。

始めましょう!

達成目標

  • Python 関数

Python 関数を定義する

Python 関数を定義するには、関数名と引数を含むこともできる一組の丸括弧の後に def キーワードを使用します。関数本体はインデントされ、: 文字の後に続きます。

新しい Python インタプリタを開きます。

python3

次は、単一の引数 x を受け取り、x の二乗を返す単純な関数の例です。

def square(x):
  return x ** 2

この例では、square 関数は単一の引数 x を受け取り、x の二乗を返します。値は return 文を使用して呼び出し元に返されます。

関数を呼び出すには、関数名の後に一組の丸括弧と必要な引数を指定します。たとえば:

result = square(5)  ## result は 25
print(result)

関数に return 文がない場合、デフォルトで None が返されます。たとえば:

def square(x):
  print(x ** 2)

result = square(5)  ## result は None
print(result)

return 文と print 文の違いを知っておく必要があります。print 文は画面に値を表示するために使用されますが、return 文は関数から値を返すために使用されます。

return 文を使用して関数の実行を早期に終了することも可能です。たとえば:

def find_first_positive(numbers):
  for number in numbers:
    if number > 0:
      return number
  return None

result = find_first_positive([-1, -2, 3, -4, 5])  ## result は 3
print(result)

この例では、find_first_positive 関数は numbers リストの最初の正数を返します。正数が見つからない場合は None を返します。return 文は正数が見つかるとすぐに関数の実行を終了します。

関数の引数

時には、関数の引数にデフォルト値を指定することが便利です。このようにすると、その引数に値を渡さずに関数を呼び出すことができ、代わりにデフォルト値が使用されます。

以下は、長方形の面積を計算する関数の例です。2つの引数を取ります:長方形の長さと幅。両方の引数にデフォルト値を指定することができるので、長さと幅が等しい場合には1つの引数だけで関数を呼び出すことができます。

def rectangle_area(length, width=1):
  return length * width

print(rectangle_area(5))  ## 出力: 5
print(rectangle_area(5, 2))  ## 出力: 10

この例では、width 引数のデフォルト値は1です。関数が1つの引数だけで呼び出された場合、width にはデフォルト値の1が使用されます。

自分で試してみてください:power という名前の関数を定義して、2つの引数:基数 x と指数 n を取ります。指数の引数を省略可能にし、デフォルト値を2にします。そして、基数と指数に異なる値を使って関数を呼び出してみてください。

def power(x, n=2):
  return x ** n

print(power(2))  ## 出力: 4
print(power(2, 3))  ## 出力: 8

引数の型ヒント

Pythonでは、関数の引数の型ヒントは、関数に渡される引数の期待される型を示します。Python 3.5で導入され、関数定義における引数名の後にコロンと型を付けて表されます。

型ヒントはオプションであり、コードの実行時の動作には影響しません。主にIDEやリンターなどのツールによって、より良いコード解析とオートコンプリートの提案を提供するために使用されます。

たとえば、以下の関数を考えてみましょう。この関数は2つの引数:整数と文字列とを取り、それらの連結を返します。

def concatenate(a: int, b: str) -> str:
    return str(a) + b

print(concatenate(1, "world")) ## "1world"

この例では、型ヒント intstr は、最初の引数 a が整数で、2番目の引数 b が文字列であることを示しています。

型ヒントはクラスとそのインスタンスでも使用できます。たとえば:

class MyClass:
    pass

def my_function(a: MyClass) -> None:
    pass

言及しておく価値があることは、型ヒントはオプションであり、コードの実行時の動作には影響しません。主にIDEやリンターなどのツールによって、より良いコード解析とオートコンプリートの提案を提供するために使用されます。

また、Pythonには typing というモジュールがあり、これには ListTupleDictSet などの便利な型が含まれており、コレクション内の要素の型についてヒントを与えるために使用できます。

from typing import List, Tuple
def my_function(a: List[int], b: Tuple[str, int]) -> None:
    pass

コードに型ヒントを使用することは、コードをより読みやすく保守しやすくするための良い慣習です。

ドキュメント文字列

ドキュメント文字列は、モジュール、関数、クラス、またはメソッド定義の最初の文として現れる文字列リテラルです。このようなドキュメント文字列は、そのオブジェクトの __doc__ 特殊属性になります。

ドキュメント文字列は、コードを文書化するために使用され、平文で書かれます。3重引用符 """ で囲まれ、通常は関数定義の最初に配置されます。

def my_function():
    """これはドキュメント文字列です。"""
    pass

ドキュメント文字列は通常、関数の短い説明、その引数、およびその戻り値を含んでいます。また、関数の動作に関するより長い説明も含めることができます。

def my_function(a: int, b: int) -> int:
    """aとbの和を返します。

    引数:
        a (int): 最初の数。
        b (int): 2番目の数。

    戻り値:
        int: aとbの和。
    """
    return a + b

複数の値を返す

Pythonでは、関数はタプルを使って複数の値を返すことができます。以下は、リストの最小値と最大値を計算する関数の例です。

def min_max(numbers):
  return min(numbers), max(numbers)

nums = [1, 2, 3, 4, 5]
min_val, max_val = min_max(nums)
print("Minimum value:", min_val)  ## 出力: "Minimum value: 1"
print("Maximum value:", max_val)  ## 出力: "Maximum value: 5"

この例では、min_max 関数は numbers リストの最小値と最大値を含むタプルを返します。関数が呼び出されるとき、このタプルは min_valmax_val の変数に展開されます。

関数から複数の値を返す別の例を以下に示します。

def get_student_info(name):
  if name == "John":
    return "John", "Doe", "Computer Science"
  elif name == "Jane":
    return "Jane", "Smith", "Physics"
  else:
    return "Unknown", "Unknown", "Unknown"

first_name, last_name, major = get_student_info("John")
print("First name:", first_name)  ## 出力: "First name: John"
print("Last name:", last_name)  ## 出力: "Last name: Doe"
print("Major:", major)  ## 出力: "Major: Computer Science"

first_name, last_name, major = get_student_info("Jane")
print("First name:", first_name)  ## 出力: "First name: Jane"
print("Last name:", last_name)  ## 出力: "Last name: Smith"
print("Major:", major)  ## 出力: "Major: Physics"

first_name, last_name, major = get_student_info("Bob")
print("First name:", first_name)  ## 出力: "First name: Unknown"
print("Last name:", last_name)  ## 出力: "Last name: Unknown"
print("Major:", major)  ## 出力: "Major: Unknown"

この例では、get_student_info 関数は学生の名前を受け取り、学生の名前、姓、専攻を含むタプルを返します。関数が呼び出されるとき、このタプルは個別の変数に展開されます。

学生の名前が認識されない場合、関数は "Unknown" の値を含むタプルを返します。

キーワード引数

Pythonでは、「キーワード引数」を使って関数の引数を指定することができます。キーワード引数を使うときは、引数名の後に値を指定し、引数の順序は任意にすることができます。

以下は、2つの引数:名前とメッセージを受け取る関数の例です。

def greet(name, message):
  print("Hello, " + name + "! " + message)

greet(message="How are you?", name="John")  ## 出力: "Hello, John! How are you?"

この例では、greet 関数は "John" と "How are you?" の引数で呼び出されていますが、引数の順序は関数で定義されている順序とは異なっています。キーワード引数を使うことで、引数の順序を任意に指定でき、コードをより読みやすくすることができます。

位置引数とキーワード引数を混ぜて使うこともできますが、位置引数は先に指定する必要があります。たとえば:

def greet(name, message):
  print("Hello, " + name + "! " + message)

greet("John", message="How are you?")  ## 出力: "Hello, John! How are you?"

この例では、name 引数は位置引数として指定され、message 引数はキーワード引数として指定されています。

キーワード引数は、関数にたくさんの引数がある場合や、引数にデフォルト値がある場合に特に便利です。たとえば:

def create_user(name, age=18, gender="unknown"):
  print("Creating user:", name, age, gender)

create_user("John")  ## 出力: "Creating user: John 18 unknown"
create_user("Jane", gender="female")  ## 出力: "Creating user: Jane 18 female"
create_user("Bob", 25, "male")  ## 出力: "Creating user: Bob 25 male"

この例では、create_user 関数は3つの引数:nameagegender を受け取ります。agegender の引数にはデフォルト値があるので、省略可能です。キーワード引数を使うことで、必要な引数だけを指定し、残りの引数にはデフォルト値を使うことができます。

Args と Kwargs

Pythonでは、可変個の引数を持つ関数を定義するために *args**kwargs の構文を使用できます。

*args 構文は、関数に可変個のキーワード付きでない引数を渡すために使用されます。たとえば:

def print_numbers(*args):
  for arg in args:
    print(arg)

print_numbers(1, 2, 3, 4, 5)  ## 出力: 1, 2, 3, 4, 5
print_numbers(10, 20, 30)  ## 出力: 10, 20, 30

この例では、print_numbers 関数は可変個の引数を受け取り、それらをコンソールに出力します。*args 構文は関数を定義するために使用され、引数はタプルとして関数に渡されます。

**kwargs 構文は、関数に可変個のキーワード付き引数を渡すために使用されます。たとえば:

def print_keywords(**kwargs):
  for key, value in kwargs.items():
    print(key, ":", value)

print_keywords(name="John", age=30, city="New York")
## 出力:
## name : John
## age : 30
## city : New York

print_keywords(country="USA", population=327000000)
## 出力:
## country : USA
## population : 327000000

この例では、print_keywords 関数は可変個のキーワード付き引数を受け取り、それらをコンソールに出力します。**kwargs 構文は関数を定義するために使用され、引数は辞書として関数に渡されます。

関数定義では、*args**kwargs 構文を他の引数と混ぜて使用できますが、*args**kwargs 引数は最後に指定する必要があります。たとえば:

def print_info(title, *args, **kwargs):
  print(title)
  for arg in args:
    print(arg)
  for key, value in kwargs.items():
    print(key, ":", value)

print_info("Person", "John", "Jane", "Bob", age=30, city="New York")
## 出力:
## Person
## John
## Jane
## Bob
## age : 30
## city : New York

この例では、print_info 関数は固定引数の title を受け取り、その後に可変個のキーワード付きでない引数 (*args) と可変個のキーワード付き引数 (**kwargs) を受け取ります。引数は定義された順序で関数に渡されます:最初に title、次に *args、最後に **kwargs

可変個の引数を受け付ける柔軟な関数を定義したい場合、*args**kwargs 構文は便利です。関数定義で硬コード化された引数名を避けることができるため、コードもより読みやすくなります。

以下は、*args**kwargs を使って引数の辞書を作成する関数の例です:

def create_dict(**kwargs):
  return kwargs

my_dict = create_dict(name="John", age=30, city="New York")
print(my_dict)  ## 出力: {'name': 'John', 'age': 30, 'city': 'New York'}

my_dict = create_dict(a=1, b=2, c=3)
print(my_dict)  ## 出力: {'a': 1, 'b': 2, 'c': 3}

この例では、create_dict 関数は可変個のキーワード付き引数を受け取り、それらを辞書として返します。**kwargs 構文は関数を定義するために使用され、引数は辞書として関数に渡されます。

関数を呼び出す際に、* 演算子を使ってリストやタプルを個々の引数に「展開」することもできます。たとえば:

def print_numbers(*args):
  for arg in args:
    print(arg)

numbers = [1, 2, 3, 4, 5]
print_numbers(*numbers)  ## 出力: 1, 2, 3, 4, 5

tuple_of_numbers = (10, 20, 30)
print_numbers(*tuple_of_numbers)  ## 出力: 10, 20, 30

この例では、* 演算子は print_numbers 関数を呼び出す際に、numbers リストと tuple_of_numbers タプルを個々の引数に展開するために使用されます。

関数を呼び出す際に、** 演算子を使って辞書をキーワード付き引数に「展開」することもできます。たとえば:

def print_keywords(**kwargs):
  for key, value in kwargs.items():
    print(key, ":", value)

my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
print_keywords(**my_dict)
## 出力:
## name : John
## age : 30
## city : New York

another_dict = {'country': 'USA', 'population': 327000000}
print_keywords(**another_dict)
## 出力:
## country : USA
## population : 327000000

この例では、** 演算子は print_keywords 関数を呼び出す際に、my_dictanother_dict 辞書をキーワード付き引数に展開するために使用されます。

ラムダ関数

Pythonでは、「ラムダ関数」を使って匿名関数を作成できます。ラムダ関数は名前のない小さな関数で、通常は1行のコードで定義および呼び出されます。

以下は、2つの引数を受け取り、それらの和を返すラムダ関数の例です。

sum = lambda x, y: x + y

result = sum(1, 2)  ## resultは3

この例では、lambda キーワードを使って、2つの引数 xy を受け取り、それらの を返すラムダ関数を定義しています。このラムダ関数は sum 変数に割り当てられ、他の関数と同じように呼び出すことができます。

同じ関数を定義するために、通常の関数の代わりにラムダ関数を使うことができますか?

def sum(x, y):
  return x + y

result = sum(1, 2)  ## resultは3

ラムダ関数は、簡単な関数を定義するためのショートカットとしてよく使われます。関数を別の関数の引数として渡したい場合や、インラインで関数を定義したい場合に特に便利です。

以下は、sorted 関数の引数としてラムダ関数を使う例です。

words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words)  ## 出力: ['apple', 'date', 'banana', 'cherry']

この例では、sorted 関数は単語のリストと、単語をどのようにソートするかを指定する「キー」関数を受け取ります。キー関数として渡されるラムダ関数は、各単語の長さを返し、単語はその長さに基づいてソートされます。

以下は、インラインでラムダ関数を定義する例です。

result = (lambda x: x ** 2)(5)  ## resultは25

この例では、ラムダ関数は1つの引数 x を受け取り、x の2乗を返します。このラムダ関数は1行のコードで定義および呼び出され、result は結果変数に割り当てられます。

ラムダ関数は、コード内の他の場所で再利用する必要のない短くて簡単な関数を定義するためにPythonで頻繁に使われます。def キーワードを使って別の関数を定義する必要なく、即座に小さな関数を定義する便利な方法です。

ローカルスコープとグローバルスコープ

Pythonでは、関数内で定義された変数はその関数に「ローカル」であり、関数内でのみ利用可能です。関数外で定義された変数は「グローバル」であり、プログラム全体で利用可能です。

以下は、グローバル変数の例です。

message = "Hello, world!"

def greet():
  print(message)

greet()  ## 出力: "Hello, world!"

この例では、message 変数は greet 関数の外で定義されているため、グローバル 変数です。greet 関数は、message 変数にアクセスして表示することができます。なぜなら、それはプログラム全体で利用可能だからです。

以下は、ローカル変数の例です。

def greet(name):
  message = "Hello, " + name + "!"
  print(message)

greet("John")  ## 出力: "Hello, John!"
print(message)  ## 出力: NameError: name 'message' is not defined

この例では、message 変数は greet 関数内で定義されているため、ローカル変数です。greet 関数は、message 変数にアクセスして表示することができますが、関数外では利用できません。関数外で message 変数にアクセスしようとすると、変数が定義されていないため NameError が発生します。

また、関数内でグローバル変数を変更するには、global キーワードを使用することもできます。たとえば:

message = "Hello, world!"

def greet():
  global message
  message = "Hello, Python!"
  print(message)

greet()  ## 出力: "Hello, Python!"
print(message)  ## 出力: "Hello, Python!"

この例では、greet 関数は global キーワードを使用して、message グローバル変数を変更しています。greet 関数は、変更された message の値を表示し、message の値は関数外でも変更されます。

一般的には、グローバル 変数を使用することを避けるのが良いです。なぜなら、それらはコードを理解して保守するのが難しくなるからです。通常は、グローバル 変数を変更する代わりに、変数を引数として関数に渡し、結果として返す方が良いです。

関数を別の関数の引数として使用する

Pythonでは、関数を別の関数の引数として渡すことができます。これは「高階関数」と呼ばれます。以下は、別の関数を引数として受け取り、それを複数回呼び出す関数の例です。

def greet(name):
  print("Hello, " + name + "!")

def call(func, args):
  for arg in args:
    func(arg)

names = ["John", "Jane", "Bob"]
call(greet, names)  ## 出力: "Hello, John!", "Hello, Jane!", "Hello, Bob!"

この例では、call 関数は2つの引数を受け取ります。関数 func と引数のリスト args です。それは、args リストの各要素を引数として func 関数を呼び出します。

自分で試してみてください。apply という名前の関数を定義して、関数と数値のリストを受け取り、関数をリストの各要素に適用した結果を含む新しいリストを返します。

def square(x):
  return x ** 2

def apply(func, numbers):
  result = []
  for number in numbers:
    result.append(func(number))
  return result

numbers = [1, 2, 3, 4, 5]
squared_numbers = apply(square, numbers)
print(squared_numbers)  ## 出力: [1, 4, 9, 16, 25]

このステップは少し難しいかもしれません。解けなかった場合は心配しないでください。飛ばして後で戻ってきても構いません。

まとめ

これまでで、Pythonの関数をどのように使うかを十分に理解しているはずです。以下は主なポイントです。

  1. Pythonの関数は、定義、呼び出し、再利用が可能なコードのブロックです。
  2. def キーワードを使って関数を定義し、その後に関数名と引数を指定します。
  3. 関数本体はインデントする必要があり、関数から値を返すには return キーワードを使えます。
  4. 関数の引数を「キーワード引数」を使って指定でき、これにより関数を呼び出す際に引数名と値を指定できます。
  5. 可変個のキーワード付きでない引数を持つ関数を定義するには *args 構文を、可変個のキーワード付き引数を持つ関数を定義するには **kwargs 構文を使えます。
  6. lambda キーワードを使って、1行のコードで定義および呼び出される匿名関数を作成できます。
  7. Pythonでは、関数内で定義された変数はその関数にローカルであり、関数内でのみ利用可能です。関数外で定義された変数はグローバルであり、プログラム全体で利用可能です。
  8. 一般的には、グローバル変数を使うことを避け、代わりに変数を引数として関数に渡し、結果として返す方が良いです。