Pythonにおける変数スコープとパラメータの仕組み

変数の有効範囲とメモリ構造

1. 変数スコープの基本概念

変数の有効範囲をスコープと呼び、同名変数でもスコープが異なれば互いに影響しません。Pythonでは変数をグローバル変数とローカル変数に分類します。

2. グローバル変数の特性

  • 関数やクラス定義の外部で宣言された変数
  • 定義されたモジュール内で有効(定義位置からモジュール終了まで)
  • 関数内でグローバル変数の値を変更する場合はglobal宣言が必要
  • 過度な使用は関数の汎用性と可読性を低下させるため注意

3. ローカル変数の特性

  • 関数本体内(仮パラメータを含む)で宣言された変数
  • グローバル変数より参照速度が速い
  • 同名のグローバル変数がある場合、関数内ではローカル変数が優先される

グローバル変数操作の実例

value = 100  # グローバル変数

def modify_global():
    global value
    print(value)
    value = 300

modify_global()
modify_global()
print(value)

実行結果:

100
300

変数名の競合テスト

value = 100

def local_test():
    value = 3  # ローカル変数
    print(value)

local_test()
print(value)  # グローバル変数は変更されない

実行結果:

3
100

パラメータ渡しのメカニズム

1. パラメータ渡しの本質

Pythonのパラメータ渡しはすべて参照渡しであり、値渡しではありません。実パラメータから仮パラメータへの代入操作はオブジェクト参照のコピーです。

  • 可変オブジェクトへの書き込み操作:元のオブジェクトを直接変更
  • 不変オブジェクトへの書き込み操作:新しいオブジェクト領域を生成

2. 可変オブジェクトの参照渡し

numbers = [10, 20]

def append_element(arr):
    print("arr id:", id(arr))
    arr.append(30)

append_element(numbers)
print("numbers id:", id(numbers))
print(numbers)

実行結果:

arr id: 45765960
numbers id: 45765960
[10, 20, 30]

3. 不変オブジェクトの参照渡し

num = 100

def process_number(n):
    print("n id:", id(n))
    n = n + 200
    print("n id:", id(n))
    print(n)

process_number(num)
print("num id:", id(num))

実行結果:

n id: 1663816464
n id: 46608592
300
num id: 1663816464

パラメータの種類と使用方法

1. 位置パラメータ

def display_values(x, y, z):
    print(x, y, z)

display_values(2, 3, 4)
# display_values(2, 3)  # エラー:必要なパラメータが不足

2. デフォルト値パラメータ

def configure_settings(a, b, c=10, d=20):
    print(a, b, c, d)

configure_settings(8, 9)
configure_settings(8, 9, 19)
configure_settings(8, 9, 19, 29)

3. 名前付きパラメータ

def show_parameters(p, q, r):
    print(p, q, r)

show_parameters(8, 9, 19)          # 位置パラメータ
show_parameters(r=10, p=20, q=30)  # 名前付きパラメータ

4. 可変長パラメータ

def process_args(a, b, *args):
    print(a, b, args)

def process_kwargs(x, y, **kwargs):
    print(x, y, kwargs)

process_args(1, 2, 3, 4)
process_kwargs(2, 3, name='yqq', age=12)

5. 強制名前付きパラメータ

def required_named(*items, b, c):
    print(items, b, c)

# required_named(2, 3, 4)  # エラー:bとcに値が代入されない
required_named(2, b=3, c=4)

タグ: Python 変数スコープ パラメータ渡し メモリ管理 関数定義

6月1日 22:42 投稿