3.1 変数と命名規則

(1/1)
本章からは、Pythonの文法について掘り下げて学んでいく。まず変数について――。

これまで何度か変数を使ってきたが、変数名として使える文字は具体的に何なのか、どのような変数名にすればいいか、変数はプログラム全体で利用できるのかについて、サンプル・プログラムを交えて解説する。
(2024年7月20日)docstringをGoogleスタイルに変更.

目次

サンプル・プログラム

変数名に使用できる文字

hoge = 1
Hoge = 2
_hoge1 = 3
print(hoge)
print(Hoge)
print(_hoge1)
このプログラムは、変数 hoge, Hoge, _hoge1 の各々に異なる数値を代入し、それを表示するだけの簡単なプログラムだ。
Python は、この3つの変数を別々のものとして識別していることが分かるだろう。hogeHoge は冒頭1文字が小文字か大文字化の違いだが、この違いにより異なる変数と認識する。また、変数名にアンダースコア _ を使うこともできる。
hoge = 1
Hoge = 2
_hoge1 = 3
print(hoge)
print(Hoge)
print(_hoge1)

# Hogeに別の数値を代入する
Hoge1 = 4
print(Hoge1)
次に、変数 Hoge にもう一度、異なる値を代入してみる。すると、最後に代入した値に置き換わっていることが分かる。このように Python の変数は再代入が可能である。
冒頭に、変数をダンボール箱のようなイメージとして描いたが、Python の変数は、すでに入っている値を取り出して、新しい値を入れるという作業は不要だ。新しい値を再代入すると、もともとあった値は消えてしまう。
1hoge = 2
print(1hoge)
今度は変数名が数字ではじまる 1hoge に数値を代入してみる。このプログラムは文法エラー(SyntaxError)を発生して終了してしまう。
Python では、変数名の頭文字に数字は使えない。
if = 2
print(if)
では、if文 と同じ名前の変数 if はどうだろうか。これも文法エラー(SyntaxError例外)を発生して終了してしまう。
Python では、文や組み込み関数などとしてあらかじめ用意している下記の名前を予約語と呼び、変数名として使うことはできない。
False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield
If = 2
print(If)
前述のように変数名は大文字と小文字を識別するので、変数名 If であれば正常に動作する。とはいえ、予約語と紛らわしいので使わない方がいい。
ほげ = 2
print(ほげ)
変数名として全角文字(厳密には Unicode文字)を利用することもできる。
ただし、アンダースコア _ 以外の記号や絵文字は使えないなど、文字種の制約が複雑であり、不具合の原因となりかねないので、Unicode文字は使わないのが無難である。
print(__file__)
変数名としてアンダースコア _ が利用できると書いたが、Python では、前後をアンダースコア2文字で囲んだ変数に特殊な意味を持たせている。このプログラムの変数 __file__ は、実行中のプログラムのパスを持っている。
他にも幾つか特別な変数があるので、変数名の前後にアンダースコア _ を付けない方が無難だ。

変数名の命名規則

第三者がプログラムを読んだときにも分かりやすいように、会社や開発プロジェクトで、あらかじめ変数名の命名規則を決めていることが多い。
趣味のプログラミングであっても、1週間、1ヶ月経つうちに、プログラムの詳しい流れを忘れてしまうものである。個人プログラムでも、命名規則を決めておいた方がいい。

このシリーズでは、次のような命名規則を用いる。
  1. 自然な英語で書く。例:year(年)
  2. 2つ以上の単語が続く場合は、2つ目以降の単語の頭文字を大文字にする。これをキャメルケースと呼ぶ。例:leapYear(うるう年)
  3. グローバル変数(後述する変数のスコープ参照)では、すべてを大文字にする。例:GREEN(緑)
  4. グローバル変数で2つ以上の単語が続く場合は、アンダースコア _ で結ぶ。これをスネークケースと呼ぶ。(例)LIGHT_YEAR(光年)

変数の削除

hoge = 1
print(hoge)
# 空文字を代入する
hoge = ""
print(hoge)
# 変数を削除する
del hoge
print(hoge)
Python では、メモリがある限り幾つでも変数を使うことができ、変数名の長さにも制約はない。ただ、何かの都合で、一度使った変数を消したいことがある。
このプログラムは、変数 hoge に数値を代入して表示し、次に空文字を再代入して表示する。こうすることで、変数の中身は消えた(空文字になった)。
変数 hoge そのものを削除したいときは、del文を使う。このプログラムは、del文 のあとの print文NameError例外が発生し、変数が存在しなくなったことを示している。

変数のスコープ

Python では、他のプログラミング言語のように変数を使うという宣言(変数宣言)を行う命令はないのだが、その変数の参照や代入ができる範囲の制限がある。これを変数のスコープと呼ぶ。
def sumNumbers(fromInt, toInt):
	"""fromIntからtoIntまでの整数を合計する.
	
	Args:
		fromInt(int):	開始値
		toInt(int):		終了値

	Returns:
		int 合計値
	"""
	n = 0
	for i in range(fromInt, toInt + 1):
		n += i
	return n
このプログラムでは、ユーザー定義関数 sumNumbers の中で使っている変数 n を、関数の外側で参照しようとすると、NameError例外が発生し、変数が存在しないことを示している。
ユーザー定義関数の中で使った変数は、その関数の中でしか通用しない。
def sumNumbers(fromInt, toInt):
	"""fromIntからtoIntまでの整数を合計する.
	
	Args:
		fromInt(int):	開始値
		toInt(int):		終了値

	Returns:
		int 合計値
	"""
	n = 0
	for i in range(fromInt, toInt + 1):
		n += i
	return n

# メイン・プログラム ========================================================
i = 1
n = 10
c = sumNumbers(i, n)
したがって、メイン・プログラムで使う変数 i, n は、ユーザー定義関数 sumNumbers の中で使っている同名変数を別の変数として識別するので、このプログラムのような実行結果になる。

定数はない

たとえば JavaScript では const宣言により定数を定義することができる。プログラミング言語における定数変数と違い、一度代入したら、二度と代入できないようになっている。
その意味ではPython には定数の概念がなく、すべて変数であり、再代入ができてしまう
たとえば消費税率のような定数は、"TAX_RATE" のように英大文字からなる変数名にしておき、運用上、再代入をしないコーディング・ルールにすることがよく行われる。

練習問題

次回予告

次回は、四則演算子を含む算術演算子と、それを文字列に対して用いたときの働きを学ぶ。

コラム:Pythonに定数はない

円周率πは定数だが、Python では math.pi によって参照することができる。
import math			# 数学関数モジュール
print(math.pi)
math.pi は、mathモジュールにあらかじめ用意されているクラス変数だ。
同じような仕組みで、消費税率をクラス変数として用意したプログラムを示す。
# 消費税をクラス変数に代入する
class myConstants:
	TAX_RATE = 0.10
	@classmethod
	@property
	def taxRate(cls):
		return cls.TAX_RATE

print(myConstants.taxRate)

# メンバ変数に再代入する
myConstants.taxRate = 0.08
print(myConstants.taxRate)
クラス変数 myConstants.taxRate に消費税率を用意しているのだが、プログラムの最後の2行で分かるように、このクラス変数は再代入が可能である。つまり、定数ではない。
先達によって、クラス変数を定数のように見せかける手法が幾つか示されているが、現時点でシンプルで完全な手法は確立されていない。
import math			# 数学関数モジュール
print(math.pi)

# math.piに再代入する
math.pi = 3.0
print(math.pi)
このプログラムを動かすと分かるように、math.pi も再代入できてしまう。

というわけで、本文の繰り返しになるが、定数は "TAX_RATE" のように英大文字からなる変数名にしておき、運用上、再代入をしないコーディング・ルールにしよう。
(この項おわり)
header