はじめに

Python において、関数(function)とは、単一の関連するアクションを実行するために使用される、整理され再利用可能なコードのブロックです。関数は、アプリケーションにより良いモジュール性を提供し、高いレベルのコード再利用性を実現します。

この実験(Lab)では、Python で関数を作成し使用するための基礎を学びます。引数を受け取る関数の定義、明確性のためのキーワード引数の使用、値の返却、ローカル変数スコープとグローバル変数スコープの違いの理解、そしてlambdaを使用した簡潔な無名関数の作成を実践します。

関数引数

このステップでは、引数を受け入れる関数を定義する方法を学習します。関数は、呼び出し時に渡される値であるarguments(引数)を受け取ることができます。

注記: WebIDE(VS Code のようなもの)の使用に慣れていない場合は、まずこちらの実験 (lab)で学習してください。

nameという引数を受け取り、パーソナライズされた挨拶を出力する関数を作成してみましょう。

まず、左側のファイルエクスプローラーからファイル arguments.py を開きます。

次に、以下のコードを arguments.py ファイルにコピー&ペーストします。このコードは、nameという 1 つの引数を取る関数 say_hello を定義しています。

## Define a function that takes one argument
def say_hello(name):
   print(f'Hello {name}')

## Call the function with a string argument
say_hello('Carlos')
say_hello('Wanda')
say_hello('Rose')

それでは、スクリプトを実行してみましょう。WebIDE でターミナルを開き、次のコマンドを実行します。

python3 arguments.py

異なる名前で関数が呼び出され、それぞれに固有の挨拶が出力されるのが確認できるはずです。

Hello Carlos
Hello Wanda
Hello Rose

これは、引数がいかにして関数を柔軟かつ再利用可能にするかを示しています。

キーワード引数

このステップでは、コードの可読性を向上させるためにキーワード引数を使用する方法を学びます。関数が複数のパラメータを持つ場合、パラメータ名を使用して、どの引数がどのパラメータに対応するかを指定できます。これをkeyword argument(キーワード引数)と呼びます。

位置引数(positional arguments)を使用する場合、渡す順序が重要になります。キーワード引数を使用する場合、順序は重要ではなくなり、コードがより明示的で理解しやすくなります。

ファイルエクスプローラーからファイル keywords.py を開きます。以下のコードをコピーして貼り付けてください。

## Function with multiple parameters
def say_hi(name, greeting):
   print(f"{greeting} {name}")

## Positional arguments: order matters
print("Calling with positional arguments:")
say_hi('John', 'Hello')

## Keyword arguments: order doesn't matter, more readable
print("\nCalling with keyword arguments:")
say_hi(name='Anna', greeting='Hi')

それでは、ターミナルからスクリプトを実行します。

python3 keywords.py

両方の関数呼び出しからの出力が表示されます。キーワード引数によって、引数の値を任意の順序で渡せることに注目してください。

Calling with positional arguments:
Hello John

Calling with keyword arguments:
Hi Anna

戻り値

このステップでは、return ステートメントを使用して関数から出力を生成する方法を探ります。print() がコンソールに値を表示するのに対し、return は関数から値を返します。この返された値は変数に格納したり、他の式で使用したりできます。

2 つの数値を受け取り、それらを加算して結果を返す関数を作成してみましょう。

ファイル returns.py を開き、次のコードを追加します。関数 sum_two_numbers は合計を計算し、return キーワードを使用して結果を出力します。

## Function that returns a value using return statement
def sum_two_numbers(number_1, number_2):
   return number_1 + number_2

## Call function and store the returned value
result = sum_two_numbers(7, 8)
print(result)

ターミナルでスクリプトを実行します。

python3 returns.py

出力は、関数が返した値であり、その値は変数 result に格納されてから出力されます。

15

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

このステップでは、ローカル変数スコープとグローバル変数スコープの違いを発見します。変数のスコープは、コード内のどこからその変数にアクセスできるかを決定します。

  • グローバルスコープ (Global Scope): どの関数外でも定義された変数はグローバルスコープにあり、関数内を含めコードのどこからでもアクセスできます。
  • ローカルスコープ (Local Scope): 関数内で作成された変数は、その関数のローカルスコープにあります。それらはその関数内でのみ存在し、外部からはアクセスできません。

まず、グローバルスコープからローカル変数にアクセスしようとした場合に何が起こるかを見てみましょう。以下のコードを実行すると、local_variable はグローバルスコープで定義されていないため、NameError が発生します。

## This code will cause an error
global_variable = 'I am available everywhere'

def some_function():
    print(global_variable)
    local_variable = "only available within this function"
    print(local_variable)

## This will raise NameError because local_variable doesn't exist here
## print(local_variable)

global ステートメント

関数内からグローバル変数を変更する必要がある場合は、global ステートメントを使用して、その意図を Python に明示的に伝える必要があります。

ファイル scope.py を開き、次のコードを追加します。ここでは、関数 spam が global キーワードを使用してグローバル変数 eggs を変更します。

## Use 'global' keyword to modify global variable from inside function
def spam():
    global eggs  ## Declare that we're modifying the global variable
    eggs = 'spam'  ## This changes the global variable

eggs = 'global'
print(f"Before calling spam(), eggs is: {eggs}")
spam()  ## Function modifies global variable
print(f"After calling spam(), eggs is: {eggs}")

それでは、スクリプトを実行します。

python3 scope.py

出力に注目してください。グローバル変数 eggs の値は、関数呼び出しによって永続的に変更されています。

Before calling spam(), eggs is: global
After calling spam(), eggs is: spam

ラムダ関数

このステップでは、lambda キーワードを使用して、無名(anonymous)の単一行関数を作成する方法を学びます。ラムダ関数は任意の数の引数を取ることができますが、式は 1 つしか持つことができません。これらは、標準の def 関数定義のオーバーヘッドなしに、小さな一時的な関数を作成するのに役立ちます。

例えば、2 つの数値を加算する通常の関数は次のようになります。

## Regular function definition
def add(x, y):
    return x + y

これは、次の lambda 関数と同等です。

## Lambda function: anonymous function defined in one line
add = lambda x, y: x + y

ラムダは、レキシカルクロージャ(lexical closures)としても機能します。つまり、作成されたエンクロージングスコープ(enclosing scope)から値を「記憶」することができます。ここでは、ラムダを返す関数を作成してみましょう。

ファイル lambdas.py を開き、次のコードを追加します。関数 make_adder は数値 n を受け取り、任意の数値 x に n を加算する新しいラムダ関数を返します。

## Lambda closure: lambda function that captures a variable from the outer scope
def make_adder(n):
    return lambda x: x + n  ## Lambda captures 'n' from the outer function

## Create a function that adds 3
plus_3 = make_adder(3)

## Use the new function
result = plus_3(4)  ## This will be 4 + 3
print(result)

ターミナルからスクリプトを実行します。

python3 lambdas.py

出力は、make_adder によって作成され返されたラムダ関数を呼び出した結果を示しています。

7

他の加算関数を作成することもできます。例えば、plus_5 = make_adder(5) は、引数に 5 を加算する関数を作成します。

まとめ

この実験(Lab)では、Python における関数の核となる概念を探求しました。関数を定義する方法、引数を使用して情報(引数)を渡す方法を学びました。関数呼び出しをより明確にするために、位置引数(positional arguments)とキーワード引数(keyword arguments)の両方を使用する練習をしました。また、return ステートメントを使用して関数に結果を出力させる方法、ローカルスコープとグローバルスコープで変数のアクセス可能性を管理する方法、そして関数外の変数を変更するために global キーワードを使用する方法についても学習しました。最後に、単純な単一行関数やクロージャを作成するための、無名ラムダ関数(anonymous lambda functions)の強力さと簡潔さに触れました。