閉じる

【Python】 変数の使い方完全入門: データを保存する書き方と注意点

プログラムでデータを扱うとき、値を一時的に保存しておく箱のような役割を持つのが変数です。

Pythonでは簡潔な書き方で変数を扱える一方で、名前の付け方や参照の仕組みを理解しないと予期せぬ挙動が起きます。

本記事では初心者がつまずきやすいポイントを避けつつ、変数の基本から実践、注意点まで体系的に解説します。

Pythonの変数とは何か

変数の役割とデータを保存する仕組み

Pythonの変数は値そのものを格納するのではなく、オブジェクトへの参照を名前に結びつけるものです。

たとえば、x = 10は数値オブジェクト10を作り、名前xをそのオブジェクトに紐付けます。

紐付けは何度でも変更でき、別の型のオブジェクトにも付け替えられます。

Python
# 変数はオブジェクトへの参照(紐付け)
x = 10          # 整数オブジェクト10にxを紐付ける
print(x, type(x))

x = "hello"     # 文字列オブジェクト"hello"へ紐付け直す
print(x, type(x))
実行結果
10 <class 'int'>
hello <class 'str'>

このようにPythonでは型宣言が不要で、同じ変数名に異なる型の値を再度紐付けできます。

代入(=)と再代入の基本

=代入演算子であり、右辺の評価結果となるオブジェクトに左辺の名前を結びつけます。

すでに同名の変数がある場合は再代入となり、以前の紐付けは上書きされます。

Python
a = 3 + 4      # 右辺を評価してaに紐付け
print(a)

a = a * 2      # aを読み出して計算し、その結果にaを紐付け直す
print(a)
実行結果
7
14

変数名の付け方(PEP 8)

PythonのスタイルガイドPEP 8では、読みやすさを最優先とし、変数名はスネークケース(snake_case)を推奨します。

英字かアンダースコアで始め、英数字とアンダースコアのみを使います。

予約語は使えません。

よくある良い例と悪い例は次の通りです。

悪い例良い例理由
xitem_count何を数えるか明確にするため
tmpfile_path一時的という曖昧さを避けるため
Datauser_data先頭大文字はクラス名に使う習慣があるため
n1, n2width, height意味を持つ語で可読性を高めるため
listitems組み込み名(list)の上書きを避けるため

組み込み名の上書きはバグの原因です。

たとえばlist = [1, 2]とすると、以後list()コンストラクタが使えなくなります。

Python
# 悪い例: 組み込み名の上書き
list = [1, 2, 3]
# print(list("abc"))  # TypeError: 'list' object is not callable になる
del list              # 使ってしまったらdelで解放して元に戻すのが一案
print(list("abc"))    # 文字列を1文字ずつのリストへ
実行結果
['a', 'b', 'c']

定数の書き方(ALL_CAPS)

Pythonには言語レベルの定数はありませんが、変更しない値はALL_CAPSで表記するのが慣習です。

これはあくまで合意であり、技術的には再代入できます。

Python
# 定数の慣習的な書き方
PI = 3.14159
MAX_RETRY = 3

print(PI, MAX_RETRY)

# 技術的には再代入できてしまう
PI = 3.14
print(PI)
実行結果
3.14159 3
3.14

Python変数の書き方と実践

初期化の基本と命名のコツ

変数は使用前に明示的に初期化すると意図が明確になります。

特に計数や合計などでは0で初期化し、文字列の構築には""、コレクションには[]{}を使います。

名前は「目的」や「単位」を含めると読みやすくなります。

Python
# 初期化の例
total_price = 0          # 合計金額(円)
user_name = ""           # ユーザー名
items = []               # 商品リスト
is_valid = False         # 妥当性フラグ

# 値の更新
total_price += 1200
user_name = "Sato"
items.append("Book")
is_valid = True

print(total_price, user_name, items, is_valid)
実行結果
1200 Sato ['Book'] True

複数代入・アンパックの使い方

Pythonは複数の値を一度に代入できます。

タプルやリストをアンパックする書き方は、読みやすくエラーも減らせます。

Python
# 複数代入
x, y = 10, 20
print(x, y)

# リスト/タプルのアンパック
point = (3, 5)
px, py = point
print(px, py)

# アスタリスク付きアンパック: 残りをまとめて受け取る
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)
実行結果
10 20
3 5
1 [2, 3, 4] 5

スワップ(値の入れ替え)の書き方

一時変数なしで値を入れ替えられるのはPythonの強みです。

Python
a, b = 1, 9
a, b = b, a  # スワップ
print(a, b)
実行結果
9 1

可読性が上がる変数名の例

可読性は保守性そのものです。

抽象的なtmpやdataを避け、文脈で特定できる名詞を使うと差が出ます。

単位や型のヒントを含めるのも有効です。

目的悪い例良い例説明
残り時間tremaining_seconds単位を含めると誤用防止に役立つ
税込金額price2total_price_with_tax意味が伝わる複合語を使用
設定ファイルのパスcfgconfig_path役割と型のニュアンスを含む
注文一覧arrordersデータの中身が分かる複数形

短さよりも明確さを優先しましょう。

変数のスコープと寿命

ローカルとグローバルの違い

スコープは名前が有効な範囲です。

関数の中で代入した変数はローカルになり、関数外の変数はグローバルです。

同名がある場合、ローカルが優先されます。

Python
x = "global"

def demo():
    x = "local"  # 関数内で代入するとローカル扱い
    print("inside:", x)

demo()
print("outside:", x)
実行結果
inside: local
outside: global

globalとnonlocalの使い方

関数内から外側の変数を書き換えたいときはglobalnonlocalを使います。

ただし使い過ぎは可読性を損なうため注意します。

Python
# globalの例: モジュールレベルの変数を更新
counter = 0

def inc():
    global counter  # グローバル変数を明示して更新
    counter += 1

inc(); inc()
print(counter)

# nonlocalの例: 一つ外側の関数スコープの変数を更新
def outer():
    count = 0
    def inner():
        nonlocal count  # 直近の外側スコープの変数
        count += 1
        return count
    print(inner(), inner(), inner())

outer()
実行結果
2
1 2 3

NameErrorの原因と対処

NameErrorは「その名前が見つからない」ときに発生します。

典型例は以下の通りです。

  • 参照前に代入していない
  • スコープの勘違い(関数内で代入してローカル化してしまう)
  • 綴りミスや大文字小文字の違い
Python
# 参照前に代入がない例
def f():
    # print(msg)  # NameError: msgはまだ定義されていない
    msg = "hi"
    return msg
print(f())

# スコープが原因の例
x = 10
def g():
    # xを読みたいだけでも、代入があるとローカル扱いになりエラー
    # print(x)      # UnboundLocalErrorになる: ローカルxが未初期化
    y = x + 1       # ← ここでxを参照しているため問題
    return y

# 対処1: 代入をやめて読むだけにする、または
def g_fixed_readonly():
    return x + 1

# 対処2: グローバルを明示
def g_fixed_global():
    global x
    x = x + 1
    return x

print(g_fixed_readonly())
print(g_fixed_global())
実行結果
hi
11
12

変数とオブジェクトの関係

参照としての変数を理解する

変数はオブジェクトの別名にすぎません。

別名同士は同じオブジェクトを指すため、片方の変更がもう片方にも見えます。

可変オブジェクトではこの性質が重要です。

Python
# 同じリストオブジェクトを指す別名
a = [1, 2]
b = a           # bはaと同じリストを参照
b.append(3)
print("a:", a, "b:", b, "same_obj:", a is b)
実行結果
a: [1, 2, 3] b: [1, 2, 3] same_obj: True

再代入とコピーの違い

再代入は名前の紐付け先を入れ替えるだけです。

コピーは新しいオブジェクトを作って中身を複製します。

浅いコピーと深いコピーの違いにも注意します。

Python
import copy

orig = [[1, 2], [3, 4]]

alias = orig                 # 参照の共有(別名)
shallow = list(orig)         # 浅いコピー(内側は共有)
deep = copy.deepcopy(orig)   # 深いコピー(内側も複製)

orig[0].append(99)           # 内側のリストを書き換え

print("orig:", orig)
print("alias:", alias)       # 共有なので変化が見える
print("shallow:", shallow)   # 浅いコピーも内側は共有なので見える
print("deep:", deep)         # 深いコピーは影響を受けない
実行結果
orig: [[1, 2, 99], [3, 4]]
alias: [[1, 2, 99], [3, 4]]
shallow: [[1, 2, 99], [3, 4]]
deep: [[1, 2], [3, 4]]

よくある落とし穴とベストプラクティス

落とし穴1: ミュータブルなデフォルト引数

関数定義時に評価され、一度作られたリストや辞書が使い回されます。

思わぬ共有を避けるにはNoneを使って内部で生成します。

Python
# 悪い例
def append_item_bad(item, bucket=[]):  # ← 一度作られたリストが使い回される
    bucket.append(item)
    return bucket

print(append_item_bad(1))
print(append_item_bad(2))  # 前回の続きになってしまう
実行結果
[1]
[1, 2]
Python
# 良い例
def append_item_good(item, bucket=None):
    if bucket is None:
        bucket = []  # 呼び出しごとに新規作成
    bucket.append(item)
    return bucket

print(append_item_good(1))
print(append_item_good(2))  # 独立したリストになる
実行結果
[1]
[2]

落とし穴2: 破壊的操作と非破壊的操作の混同

例えばlist.appendは破壊的で戻り値はNoneです。

Python
nums = [1, 2]
result = nums.append(3)  # 破壊的: numsを書き換える。戻り値はNone
print(nums, result)
実行結果
[1, 2, 3] None

ベストプラクティスとして次の指針が有益です。

  • 意味のある名前を付け、スネークケースに従う
  • 不変にしたい値はALL_CAPSで表す
  • 可変オブジェクトの共有に注意し、必要ならコピーする
  • スコープを意識し、globalやnonlocalの多用は避ける

まとめ

本記事では、Pythonの変数はオブジェクトへの参照であり、代入は名前の紐付けを変える操作であることを中心に、命名規則、スコープ、アンパックやスワップの実践、コピーの考え方、そして落とし穴と対策までを丁寧に解説しました。

特に可変オブジェクトの共有スコープ起因のNameErrorは初心者がつまずきやすい部分です。

意味のある変数名とPEP 8に基づくスタイルを心がけ、必要に応じて浅いコピー・深いコピーを使い分ければ、予期せぬバグを効果的に防げます。

最後に、定数はALL_CAPSで意図を伝え、読みやすいコードを常に目指すことが上達への近道です。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!