112

choice2 に等しいという名前の変数があるとします。変数の名前にアクセスするにはどうすればよいでしょうか。に相当するもの

In [53]: namestr(choice)
Out[53]: 'choice'

辞書作成に使用します。これを行うには良い方法があり、私はそれを見逃しています。

編集:

これを行う理由はこうです。実行時に調整したい、または調整したくない複数のパラメーターを使用してプログラムを呼び出すデータ分析を実行しています。次の形式の .config ファイルから、前回の実行で使用したパラメーターを読み込みました。

filename
no_sig_resonance.dat

mass_peak
700

choice
1,2,3

値を求めるプロンプトが表示されると、以前に使用された値が表示され、空の文字列を入力すると、以前に使用された値が使用されます。

私の質問は、これらの値がスキャンされた辞書を作成するときに発生するためです。パラメータが必要な場合はget_param、ファイルにアクセスしてパラメータを見つけるを実行します。

を読むことで、問題を一挙に回避できると思います。config一度ファイルを作成し、そこから辞書を作成します。私はもともとそれを避けていました...理由はもう覚えていません。コードを更新するのに最適な状況です!

4

8 に答える 8

131

あなたが主張するなら、ここにいくつかの恐ろしい検査ベースの解決策があります。

import inspect, re

def varname(p):
  for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
    m = re.search(r'\bvarname\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', line)
    if m:
      return m.group(1)

if __name__ == '__main__':
  spam = 42
  print varname(spam)

あなたが抱えている問題を再評価し、別のアプローチを探すきっかけになることを願っています。

于 2009-02-26T23:05:16.963 に答える
88

元の質問に答えるには:

def namestr(obj, namespace):
    return [name for name in namespace if namespace[name] is obj]

例:

>>> a = 'some var'
>>> namestr(a, globals())
['a']

@rbrightがすでに指摘しているように、あなたが何をするにしても、おそらくそれを行うためのより良い方法があります。

于 2009-02-26T23:14:46.130 に答える
16

これを行おうとしている場合は、何か間違ったことをしていることを意味します。dict代わりにa の使用を検討してください。

def show_val(vals, name):
    print "Name:", name, "val:", vals[name]

vals = {'a': 1, 'b': 2}
show_val(vals, 'b')

出力:

Name: b val: 2
于 2009-02-26T22:52:50.550 に答える
8

特定の解決策の詳細を尋ねるのではなく、直面している問題について説明することをお勧めします。より良い答えが得られると思います。私がこれを言うのは、あなたがやろうとしていることが何であれ、それを行うためのより良い方法がほぼ確実にあるからです. この方法で変数名にアクセスすることは、通常、どの言語でも問題を解決するために必要ではありません。

つまり、すべての変数名は、組み込み関数localsおよびglobalsを介してアクセスできる辞書に既に含まれています。検査するスコープに適したものを使用してください。

これらの辞書を検査するためのいくつかの一般的なイディオムの 1 つは、簡単な文字列補間のためのものです。

>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe

この種のものは、変数を名前で検査する必要がありますが、代替手段よりも少し読みやすい傾向があります。

于 2009-02-26T22:49:37.173 に答える
4

熱心な評価では、変数は基本的に、(言い換えれば) 見るたびにその値に変わります。そうは言っても、Python には組み込みの名前空間があります。たとえば、locals() は関数の変数名をその値にマッピングする辞書を返し、globals() はモジュールに対して同じことを行います。したがって:

for name, value in globals().items():
    if value is unknown_variable:
        ... do something with name

locals() と globals() にアクセスできるようにするために何もインポートする必要がないことに注意してください。

また、値に複数のエイリアスがある場合、名前空間を反復処理すると、最初のエイリアスのみが検出されます。

于 2009-02-26T22:45:40.037 に答える
2

構成パラメーターを読み取る方法に関する改訂された質問については、時間と労力を節約し、ConfigParserまたは (私の好みのツール) ConfigObjを使用することを強くお勧めします。

それらは必要なすべてのことを実行でき、使いやすく、他の誰かがそれらを適切に動作させる方法についてすでに心配しています!

于 2009-02-26T23:39:04.917 に答える
2

このようなものはあなたのために働くでしょうか?

>>> def namestr(**kwargs):
...     for k,v in kwargs.items():
...       print "%s = %s" % (k, repr(v))
...
>>> namestr(a=1, b=2)
a = 1
b = 2

そしてあなたの例では:

>>> choice = {'key': 24; 'data': None}
>>> namestr(choice=choice)
choice = {'data': None, 'key': 24}
>>> printvars(**globals())
__builtins__ = <module '__builtin__' (built-in)>
__name__ = '__main__'
__doc__ = None
namestr = <function namestr at 0xb7d8ec34>
choice = {'data': None, 'key': 24}
于 2009-02-26T23:01:26.490 に答える