変数と定数

これまたあまり説明の余地はないかも知れませんが、変数定数について学びます。まさにネタバレ状態ですが、Pythonには定数といわれるものはありません。本稿ではPythonの変数について学習するとともに、定数が欲しいときにどのようにすれば良いのかについても触れます。

ここで学習すること

  • 変数
  • 定数

説明

変数

まずは変数からです。

変数とは端的に言えばデータを入れておく入れ物で、ひとまずは数学における変数と同じです。

こんな ↓ 感じです。(まぁ、xもyもzも全部変数ですが…)

value1 = 123
_value1 = 123
first_name = "john"
LAST_NAME = "Doe"

Python の 変数 は、アンダースコアー(_)および英数字により命名可能で、最初の1文字目には数字は使えません。

とまぁ、古い説明や余計なことは知らなくて良いという判断が働いてか、このような説明がされていることが多いです。

ですが、実際にはUnicode文字つまり、日本語の変数名も定義可能です。

定数

次に定数です。一般的に定数とは一度代入した値は変更が効かないという特性をもった変数です。

Javaだとfinal修飾子、JavaScriptならconstなどで定義可能なように、一度変数に格納したデータの変更が効かないようにする機構を提供している言語は数多くあります。が、残念か残念でないかは別にして、Pythonには定数がありません

従って、本質的な意味では、この「定数」という項目には説明することがありません。

ところが、(こちらは残念なことに)定数として扱いたいという欲求は、人がプログラムを書く以上は防ぎようがありません。

解決策1

最もシンプルな方法は、命名規則によって「そのように扱う」です。

「全て大文字で区切はアンダースコア」というルールで命名した変数は定数として扱いましょうね、というルールで縛るというものです。

なんとも性善説に基づいた危うい解決策ですね。

当然そのように扱っているだけで、言語としては普通の変数ですので、いくらでも書き換えらレテしまいます。

解決策2

Pythonとて誰かがプログラミングしたものであって、定数のあるJavaやJavaScriptもまた誰かがプログラミングしたものです。ということで、そのような振る舞いをするものを作ってしまえば解決策になるという考え方です。

それが次のコードに示されているように、そのためにクラスを作ってしまいます。

クラスの変数を変更しようとするとエラーが発生するようにしたものです。具体的にはすでにその変数名が存在していたら変更で、初めて値をセットしようとすると変数が存在しないので値を格納するのを許すという構造です。

自由に変数名を付けられるために、__setattr__()やself.__deict__[]などが登場していますが、ひとまず細かいことは覚える必要は無く、便利に使い始めても良いでしょう。

ファイル名はconst.pyとし、クラスの定義を実際にやってみます。

import sys


class _const:
    class ConstError(TypeError):
        pass

    def __setattr__(self, name, value):
        if name in self.__dict__:
            raise self.ConstError("Can't rebind const (%s)" % name)
        self.__dict__[name] = value


sys.modules[__name__] = _const()

使い方は以下のような感じです。

import const

const.MAX_RETRY = 100
const.MAX_RETRY = 200

実行してみます。

(LearningPython) MacBookPro:050.var_const $ python sample.py 
Traceback (most recent call last):
  File "sample.py", line 6, in 
    const.MAX_RETRY = 200
  File "/Users/kazuto/git/LearningPython/src/PythonBasics/050.var_const/const.py", line 10, in __setattr__
    raise self.ConstError("Can't rebind const (%s)" % name)
const.ConstError: Can't rebind const (MAX_RETRY)
(LearningPython) MacBookPro:050.var_const $ 

なんとまぁ長々と出ていますが、値100はセットできて、200の時にエラーとなるのが分かったかと思います。

大勢の開発者が参加する場合、これに限らず性善説ではコストがかかりすぎるということはあると思います。そんな場合には解決策2のタイプの仕組みが良いかも知れませんが、解決策1で対応している例も多いので、周りに迷惑をかけないためにも、解決策1で慣れておくというのも重要かも知れません。