python変数名の実現方法詳細


もしプログラムを書くなら、x 1を1にして、x 2を2にして、x 100を100にするまではどうしますか?
Cのような静的な言語では、変数名という識別子は実際にはコンパイラによってメモリアドレスに直接翻訳されますので、手動で各変数の値を設定する以外には、これはできません。Pythonというダイナミックな言語はできる。
最も容易に考えられるのはevalですが、実際にはこのような危険なものは必要ありません。Pythonの変数名は辞書のkeyです。この辞書を取得するには、直接locasとglobals関数を使ってください。
このプログラムはこのように実現できます。
コードは以下の通りです

>>> names = locals()

>>> for i in xrange(1, 101):

...  names['x%s' % i] = i

...

>>> x1

1

>>> x2

2

>>> x100

100
しかし、この例はあまり役に立たないと言われるかもしれません。やはり行列で実現するのがもっと実用的です。
もう一つの例を考えると、サーバーはオブジェクトデータベースを使用して、オブジェクトを直接データベースに保存することができます。サーバーは現在サポートされているすべてのクラスを一覧表示しますが、ユーザーはリストに存在しないクラスを追加したいので、JSONまたはXMLテキストをサーバーに送信します。サーバはこのテキストを解析して、クラスのオブジェクトに変換し、クラス名を設定します。その後、ユーザーはこのクラスのオブジェクトを任意に生成することができます。
このデータベースはクラス名と関連しています。共通のObject類を使ってすべてのオブジェクトを保存してはいけません。そうでないと照会時に混乱します。
ちょうど、ある人はGAEフォーラムでこの需要を提出しました。Javaしかできない彼は最終的に諦めます。
もちろん、いたずらに使ってもいいです。
コードは以下の通りです

>>> locals()['True'] = False

>>> True

False
もう一つの用途は、変数名が既に存在するかどうかをテストすることです。標準的なやり方はtry…exceptのNameErr異常ですが、実際には直接in locars()またはin globals()で判断できます。
ついでにもう一つの変わった方法を紹介します。このように書いた人がいるかどうかは分かりません。
コードは以下の通りです

>>> import __main__

>>> hasattr(__main__, 'x')

False

>>> setattr(__main__, 'x', 1)

>>> x

1

>>> hasattr(__main__, 'x')

True
もちろん、誰もあなたにこのように書くことを勧めません。私もできません。
最後に、変数名を動的に設定する以外に、動的に削除することもできます。例えば、del local()['x 1'。同様に、delattrも利用可能です。
知識点拡張:
python変数の変数名を動的に取得します。
需要目標:上の動的命名リストがある場合、変数の変数名を動的に取得するには、次のような操作が必要です。
python原生のinspectライブラリを利用して実現します。
コアコード:

import inspect
def get_variable_name(variable):
  callers_local_vars = inspect.currentframe().f_back.f_locals.items()
  return [var_name for var_name, var_val in callers_local_vars if var_val is variable]
テストコード:

def get_variable_name(variable):
  callers_local_vars = inspect.currentframe().f_back.f_locals.items()
  return [var_name for var_name, var_val in callers_local_vars if var_val is variable]


if __name__ == '__main__':
  prepare_list = locals()
  for i in range(16):
    prepare_list['list_' + str(i)] = []
    prepare_list['list_' + str(i)].append(('   ' + str(i)) + ' list')
  a = get_variable_name(prepare_list['list_0']).pop()
  b = get_variable_name(prepare_list['list_1']).pop()
  print(a)
  print(b)