Pythonの関数とモジュールの復習

1. 関数

コードを書くアプローチは、手続き型プログラミングから関数型プログラミング、そしてオブジェクト指向プログラミングへと進化してきました。

1.1 関数の基本

関数は、特定のタスクを実行するためのコードブロックです。引数を受け取り、結果を返すことができます。

def sample_function(param1, param2):
    # 関数の処理
    pass

result = sample_function(10, 20)

1.2 引数

関数のデフォルト引数には、可変型(リストや辞書など)を慎重に使用する必要があります。可変型をデフォルト値として使用すると、意図しない動作を引き起こす可能性があります。

例えば、空のリストをデフォルト値として設定したい場合、以下の「悪い例」は避けるべきです。

# 悪い例(落とし穴)
def process_data(data, default_list=[]):
    default_list.append(data)
    return default_list

# 良い例
def process_data_safe(data, default_list=None):
    if default_list is None:
        default_list = []
    default_list.append(data)
    return default_list

なぜ「悪い例」が問題になるかを見てみましょう。

def add_item(item, container=[]):
    container.append(item)
    return container

list1 = add_item('apple')  # ['apple']
list2 = add_item('banana', ['grape'])  # ['grape', 'banana']
list3 = add_item('cherry')

print(list1)  # 出力: ['apple', 'cherry']
print(list2)  # 出力: ['grape', 'banana']
print(list3)  # 出力: ['apple', 'cherry']

この結果は、デフォルトの空リストが関数の呼び出し間で共有されていることを示しています。

面接問題

  • def func(a, b=[]): にはどのような落とし穴がありますか?

答え: `b` がリストのような可変型であるため、引数を渡さない場合、デフォルト値として同じメモリ上のオブジェクトが使用されます。

1.3 戻り値

関数は、値を返すことができます。また、関数の中に別の関数を定義し、それを返すことで、クロージャを作成できます。

def create_greeter(name):
    def greeter():
        print(f"Hello, {name}!")
        return 42
    return greeter

g1 = create_greeter("Alice")
g2 = create_greeter("Bob")

g1()  # Hello, Alice! と 42 を出力
g2()  # Hello, Bob! と 42 を出力

クロージャ

クロージャは、内側の関数が外側の関数のスコープにある変数を「記憶」する関数です。

# これはクロージャではない
def not_closure(name):
    def inner():
        return 99
    return inner

# これはクロージャである
def is_closure(name):
    def inner():
        print(name)  # 外側のスコープの変数 name を使用している
        return 99
    return inner

1.4 スコープ

スコープとは、変数が参照可能な範囲のことです。Pythonには、ローカルスコープ、グローバルスコープ、そして非ローカルスコープがあります。

1.5 再帰

再帰とは、関数が自分自身を呼び出すことです。このアプローチは、問題をより小さな部分問題に分割するのに役立ちますが、過度な使用はパフォーマンスの低下を招くことがあります。

# 基本的な再帰の例:カウントダウン
def countdown(n):
    if n < 0:
        return
    print(n)
    countdown(n - 1)

countdown(3)
# フィボナッチ数列を計算する再帰関数
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(5))  # 5
# 階乗を計算する再帰関数
def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

print(factorial(5))  # 120

2. モジュール

モジュールは、関連する関数、クラス、変数をまとめたファイルです。Pythonには、多くの組み込みモジュールが用意されています。

  • hashlib: ハッシュ値(MD5, SHAなど)を生成するために使用されます。
  • random: 乱数を生成するために使用されます。
  • getpass: ユーザーにパスワードを安全に入力させるために使用されます。
  • time: 時間関連の操作(現在時刻の取得、スリープなど)を行うために使用されます。

タグ: Python 関数 モジュール クロージャ 再帰

6月6日 00:27 投稿