dictionaries を使用してこれを実現できます。辞書はキーと値のストアです。
>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'y': 2, 'x': 1, 'z': 3}
>>> dct["y"]
2
変数キー名を使用して、セキュリティリスクなしで変数変数の効果を実現できます。
>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'
次のようなことを考えている場合
var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...
リストは辞書よりも適切かもしれません。リストは、整数のインデックスを持つオブジェクトの順序付きシーケンスを表します。
l = ['foo', 'bar', 'baz']
print(l[1]) # prints bar, because indices start at 0
l.append('potatoes') # l is now ['foo', 'bar', 'baz', 'potatoes']
順序付きシーケンスの場合、リストは整数キーを持つ辞書よりも便利です。リストはインデックス順の反復、 スライス 、append
、および辞書による扱いにくいキー管理を必要とするその他の操作をサポートするためです。
組み込みの getattr
関数を使用して、名前でオブジェクトの属性を取得します。必要に応じて名前を変更します。
obj.spam = 'eggs'
name = 'spam'
getattr(obj, name) # returns 'eggs'
変数変数を使用したいときはいつでも、辞書を使用したほうがいいでしょう。だから書く代わりに
$foo = "bar"
$$foo = "baz"
あなたが書く
mydict = {}
foo = "bar"
mydict[foo] = "baz"
この方法では、以前の既存の変数(セキュリティの側面)を誤って上書きすることはなく、異なる「名前空間」を持つことができます。
新しいコーダーは時々このようなコードを書きます:
my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...
次に、コーダーには、O(m * n)のコーディング努力で、名前付き変数の山が残されます。ここで、mは数値です名前付き変数のnは、変数のグループにアクセスする必要がある回数(作成を含む)です。賢明な初心者は、これらの各行の唯一の違いがルールに基づいて変化する数値であることに気付き、ループを使用することにします。ただし、これらの変数名を動的に作成する方法にこだわっており、次のようなことを試みる場合があります。
for i in range(10):
my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)
彼らはすぐにこれが機能しないことに気付きます。
プログラムが任意の変数「名前」を必要とする場合、他の回答で説明されているように、辞書が最良の選択です。ただし、単純に多くの変数を作成しようとしていて、整数のシーケンスでそれらを参照することを気にしない場合は、おそらくlist
を探しています。これは、毎日の温度測定値、毎週のクイズスコア、またはグラフィカルウィジェットのグリッドなど、データが均一である場合に特に当てはまります。
これは次のように組み立てられます。
my_calculator.buttons = []
for i in range(10):
my_calculator.buttons.append(tkinter.Button(root, text=i))
このlist
は、内包表記を使用して1行で作成することもできます。
my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]
どちらの場合でも、結果は、my_calculator.buttons[0]
で最初の要素にアクセスし、my_calculator.buttons[1]
で次の要素にアクセスするなど、list
が設定されます。 「ベース」変数名はlist
の名前になり、それにアクセスするために可変識別子が使用されます。
最後に、set
などの他のデータ構造も忘れないでください。これは辞書に似ていますが、各「名前」には値が付加されていない点が異なります。単にオブジェクトの「バッグ」が必要な場合、これは素晴らしい選択です。このようなものの代わりに:
keyword_1 = 'Apple'
keyword_2 = 'banana'
if query == keyword_1 or query == keyword_2:
print('Match.')
これがあります:
keywords = {'Apple', 'banana'}
if query in keywords:
print('Match.')
類似オブジェクトのシーケンスにはlist
を、オブジェクトの任意の順序のバッグにはset
を、関連する値を持つ名前のバッグにはdict
を使用します。
辞書の代わりに、コレクションモジュールの namedtuple
を使用することもできます。これにより、アクセスが容易になります。
例えば:
# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])
# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
vars = Variables(34, 45)
print(vars.first, vars.second)
SimpleNamespace
クラスを使用して、setattr
で新しい属性を作成するか、サブクラスSimpleNamespace
を作成して、独自の関数を作成して新しい属性名(変数)を追加できます。
from types import SimpleNamespace
variables = {"b":"B","c":"C"}
a = SimpleNamespace(**variables)
setattr(a,"g","G")
a.g = "G+"
something = a.a
globals()
built in method を使用して、その動作を実現する必要があります。
def var_of_var(k, v):
globals()[k] = v
print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print variable_name # 123
some_name = 'variable_name2'
var_of_var(some_name, 456)
print variable_name2 # 456
オブジェクトを使用したくない場合でも、現在のモジュール内でsetattr()
を使用できます。
import sys
current_module = module = sys.modules[__name__] # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15) # 15 is the value you assign to the var
print(variable_name) # >>> 15, created from a string
globals()
を使用します
たとえば、グローバルスコープi_1
、i_2
... i_10
でアクセスできる10個の変数が必要な場合、実際に変数をグローバルスコープに動的に割り当てることができます。
for i in range(10):
globals()['i_{}'.format(i)] = 'a'
これにより、これら10個の変数すべてに「a」が割り当てられます。もちろん、値を動的に変更することもできます。これらの変数はすべて、他のグローバルに宣言された変数と同様にアクセスできます。
>>> i_5
'a'
私は質問に答えています: 文字列で名前が指定された変数の値を取得する方法? この質問へのリンクを持つ複製として閉じられます。
問題の変数がオブジェクトの一部(クラスの一部など)である場合、正確に達成するためのいくつかの便利な関数はhasattr
、getattr
、およびsetattr
です。
したがって、たとえば次のことができます。
class Variables(object):
def __init__(self):
self.foo = "initial_variable"
def create_new_var(self,name,value):
setattr(self,name,value)
def get_var(self,name):
if hasattr(self,name):
return getattr(self,name)
else:
raise("Class does not have a variable named: "+name)
その後、次のことができます。
v = Variables()
v.get_var("foo")
「initial_variable」
v.create_new_var(v.foo,"is actually not initial")
v.initial_variable
「実際には初期ではない」
変数のコンテナをエミュレートする既知の方法があります。これは、変数名と文字列キーによるアクセスの両方の方法をサポートします。
class Vars:
def __init__(self, **kw):
self.__dict__.update(kw)
def __getitem__(self, key):
return self.__dict__[key]
def __setitem__(self, key, val):
self.__dict__[key] = val
def __contains__(self, name):
return name in self.__dict__
def __nonzero__(self):
return bool(self.__dict__)
def __iter__(self):
return iter(self.__dict__)
def __len__(self):
return len(self.__dict__)
def __copy__(self):
return self.__class__(**self.__dict__)
def __repr__(self):
return 'Vars(' + ', '.join('%s=%r' % (k,v) for k,v in self.__dict__.items()) + ')'
>>> vars = Vars()
>>> vars.a = 1
>>> vars['b'] = 2
>>> print(vars)
Vars(a=1, b=2)
>>> print(vars['a'], vars.b)
1 2
>>> print(Tuple(vars))
('a', 'b')
コンセンサスは、このために辞書を使用することです-他の回答を参照してください。ほとんどの場合、これは良い考えですが、これには多くの側面があります。
そうは言っても、上記のアイデアの一部を提供する 変数変数マネージャー -classを実装しました。 python 2および3で機能します。
次のように クラス を使用します。
from variableVariablesManager import VariableVariablesManager
myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])
# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
print("not allowed")
except AttributeError as e:
pass
# rename a variable
myVars.renameVariable('myconst', 'myconstOther')
# preserve locality
def testLocalVar():
myVars = VariableVariablesManager()
myVars['test'] = 13
print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])
# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
myVars = VariableVariablesManager()
print("inside function myVars['globalVar']:", myVars['globalVar'])
myVars['globalVar'] = 13
print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])
同じタイプのみで変数の上書きを許可する場合:
myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)
変数ランタイムを作成するには、次の例を参照してください。 globals()
を使用できます。
for i in range(3):
globals() ['variable_'+str(i)] = i
上記の例では、実行時にそれぞれ値0、1、2の3つの変数variable_0
、variable_1
、variable_2
を作成します。
variable_0
[Output]:0
variable_1
[Output]:1
variable_2
[Output]:2
実行時に作成された変数の値にアクセスするには、次のようにeval()
メソッドを使用できます。
for i in range(3):
globals() ['variable_'+str(i)] = i
print('Variable Value:',eval('variable_'+str(i)))
[Output]:
Variable Value: 0
Variable Value: 1
Variable Value: 2
変数のセットもクラスにまとめることができます。 __dict__属性を介して組み込み辞書に直接アクセスすることにより、実行時にクラス変数に「変数」変数を追加できます。
次のコードは、構築中にインスタンスに変数(この場合は属性)を追加するVariablesクラスを定義します。変数名は、指定されたリストから取得されます(たとえば、プログラムコードによって生成された可能性があります)。
# some list of variable names
L = ['a', 'b', 'c']
class Variables:
def __init__(self, L):
for item in L:
self.__dict__[item] = 100
v = Variables(L)
print(v.a, v.b, v.c)
#will produce 100 100 100
組み込み関数vars()
を使用できます
>>> foo = 'bar'
>>> vars()[foo] = 'something'
>>> bar
'something'