個別の変数の辞書を作成するより簡単な方法は?


220

変数の名前を文字列として取得できるようにしたいのですが、Pythonにそれほど多くのイントロスペクション機能があるかどうかはわかりません。何かのようなもの:

>>> print(my_var.__name__)
'my_var'

私は次のような辞書にしたい変数がたくさんあるのでそれをやりたいです:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

しかし、それよりももっと自動化したいのですが。

Pythonは持っているlocals()vars()私は方法があると思いますので、。


31
何が求められているかについて人々は混乱しているようですので、興味深い質問なので、ここで述べます。配列[foo、bar、baz]を指定すると、{'foo':foo、 'bar':bar、 'baz':baz}のようなディクショナリが必要であり、配列内の変数がわからない。質問者は、Pythonで変数の名前を文字列として取得する方法を尋ねています。うまくいけば、人々がひどい応答をナビゲートして、これがpythonで本当に良いアイデアではない理由を学ぶいくつかの場所を見つけることができます。
Jesse Sherlock、


2
テクニックの1つの使用法は、文字列のフォーマット呼び出しを合理化することです: '{var} {foo} {bar}'。format(** named(var、foo、bar))。ここで、「named」はdict( 'var':var)説明どおり。
Gordon Bean

4
名前はオブジェクトにマッピングされているため、これは実際には悪い質問だと思います。同じオブジェクトを指す複数の名前を付けることができ、そのマッピングを反転するという目標を達成する必要を見たことはありません。したがって、ここで間違った答えが受け入れられたということは意味がありません-グーグル検索があなたをここに連れてきた場合、あなたは明らかに間違った質問をしています。
アーロンホール

1
これはデバッグに最適です。
john ktejik 2017年

回答:


48

これをしようとしていますか?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

1
rlotunは名前を発見できるため、最初の「精神」に近いです。私はあなたの両方のアンサーを使うことができます。または、たぶん私の手でタイプしてください。いくつかのものは、ただ...自動化されると判断されていない
電子サティスを

7
@ e-satis:@rlotunが機能するためには、変数のリストを提供する必要があります。変数のリストがある場合、それらの名前を「発見」する意味は何ですか?
S.Lott、2010年

4
ローカルとグローバルを明示的に使用する代わりになぜ評価するのですか?

1
@Roger Pate:全体のエクササイズのポイントが何なのかわからなかったので。
S.Lott、2010年

242
この答えは、尋ねられた質問には答えません。 変数のリストがある場合、それらの名前を「発見」する意味は何ですか?重複を回避して、変数の名前を2回書き込むことなく、同じ出力を書き込むprint('x: ' + x)ことができるようにmagic_print(x)します。
Piotr Dobrogost 2013年

130

unwindが言ったように、これは実際にはPythonで行うことではありません。変数は実際にはオブジェクトへの名前のマッピングです。

ただし、これを試す1つの方法は次のとおりです。

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

14
このアイデアにはメリットがありますが、2つの変数名が同じ値を参照している場合(例True:)、意図しない変数名が返される可能性があることに注意してください。
unutbu

14
なぜid(v) == id(a)代わりにv is a?これは、int、string、および同様に実装されたユーザー定義型など、複数の変数にバインドされたオブジェクトでは失敗します。

はい、v is aより良い選択です。そして、はい、起こり得るすべての潜在的な落とし穴を考えると、確かに危険です!;-)
rlotun

16
@ e- satis rlotunは名前を見つけることができるので、rlotunは最初の「精神」に近いというコメントに同意するので、この回答を回答としてマークしていないことに驚いています。さらに、S.Lottの答えはあなたの質問をまったく肯定しません...
ピョートル・ドブロゴスト2013年

2
「やりすぎで危険」...そしてevalを使うのではないですか?
バグ

63

私はこれをかなりやりたかったです。このハックはrlotunの提案に非常に似ていますが、それは私にとって重要なワンライナーです:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

Python 3以降

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

3
@keflavich私はこのアプローチがとても好きで、時々それを使ってきました。ただし、関数内で機能させることはできません。それを行うには「より良い」方法があると思いますが、nbubisが言うほど簡単ではありません。これを関数keflavichで使用できましたか?ここで私はこれについて質問します。
レオ

10
Pythonの3に、という注意iteritems()に置き換えられてitems()
ジョナサン・ウィーラー

これは信頼できません:spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)出力spam
andreasdr

1
@andreasdrが原因spam = 1, blah = 1; assert spam is blahです。プリミティブデータ型を比較す​​ると、ソリューションが壊れます。
2018

17

これはハックです。すべてのPython実装ディストリビューション(特に、traceback.extract_stack。がないディストリビューション)では機能しません。

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

このハックは壊れやすいことに注意してください:

make_dict(bar,
          foo)

(2行でmake_dictを呼び出す)は機能しません。

fooとからdictを生成しようとする代わりにbar、文字列変数名 'foo'とからdictを生成する方がはるかにPythonic 'bar'

dict([(name,locals()[name]) for name in ('foo','bar')])

1
スマートハックの+1。もちろん、トレースバックは非常に遅いため、使用するのが遅い場合があります。
e-

1
+1111111 !!!! うんそれは遅いですが、print("a_very_long_name: {}'.format(a_very_long_name))気にする人を置き換えるために使用するとき!
frnhr '12

14

これはPythonでは不可能です。Pythonには「変数」がありません。Pythonには名前があり、同じオブジェクトに複数の名前が存在する場合があります。


ええ、わかっています。質問を単純にしましたが、「get_var_tags(var)[0]」のようなものをもっと期待していました。
e-satis 2010年

10

私の問題は、この質問がなぜ有用であるかを説明するのに役立つと思います。それは、それへの答え方についてもう少し洞察を与えるかもしれません。コード内のさまざまな変数のインラインヘッドチェックをすばやく行うための小さな関数を書きました。基本的に、変数名、データ型、サイズ、その他の属性がリストされているので、私が犯した間違いをすばやく見つけることができます。コードは簡単です:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

したがって、複雑な辞書/リスト/タプルの状況がある場合、インタープリターに割り当てた変数名を返させると非常に便利です。たとえば、以下は奇妙な辞書です。

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

これを正しい場所に置いたかどうかはわかりませんが、役立つと思いました。私はそれがそうであることを望みます。


だからあなたの頭のチェックで、それは変数/名前がコードの異なる時間に異なるものを指すことができるという事実を説明しますか?たとえばmyconnection、ある時点ではブール値を、別の時点では整数を、コード実行の別の時点ではソケット接続を指している可能性がありますか?

9

この質問への回答に基づいて、きちんとした便利な関数を書きました。役に立つので、ここに置いておきます。

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

使用法:

>> a = 4
>> what(a)
a = 4
>>|

6

特定の値のリストが既にある場合は、@ Sで説明されている方法がわかります。ロットは最高です。しかし、方法は、下記のすべての変数とコード全体で追加されたクラスを取得するためにうまく機能なし希望する場合は、あなたがそれらを指定することができますが、変数名を提供する必要があります。コードを拡張してクラスを除外できます。

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

出力:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

6

Python 3ではこれは簡単です

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

これは印刷されます:

myVariable 5


これはrlotunのアプローチに似ていますが、少し単純です
officialhopsof

10
-1。新しいインタープリターウィンドウを開いて、を試してくださいfor v in locals()
エア

私はあなたが何を意味するのか完全にわかりませんか?
officialhopsof

4
これによりエラーが発生します。RuntimeError:ディクショナリの反復中にサイズが変更されました...
Nizar B.

2
しかし、あなたはできるfor v in list(locals()):
Phylliida '21

5

Python3。inspectを使用して、呼び出し元のローカル名前空間をキャプチャしてから、ここに提示されているアイデアを使用します。指摘されているように、複数の回答を返すことができます。

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

良い答えですが、私にとっては次の方が良いです:... id(eval(name、None、frame.f_back.f_locals))== ...
Emmanuel DUMAS

5

これが、変数名を読み取るために作成した関数です。より一般的で、さまざまなアプリケーションで使用できます。

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

指定された質問でそれを使用するには:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

4

スレッドを読んで、私はひどい摩擦を目にしました。悪い答えを出してから、誰かに正しい答えを出させるのは簡単です。とにかく、ここに私が見つけたものがあります。

差出人:[effbot.org](http://effbot.org/zone/python-objects.htm#names

名前は少し異なります。それらは実際にはオブジェクトのプロパティではなく、オブジェクト自体はそれが何と呼ばれるかを認識していません。

オブジェクトには任意の数の名前を付けることができます。名前を付けないこともできます。

名前は名前空間に存在します(モジュール名前空間、インスタンス名前空間、関数のローカル名前空間など)。

注:これは、オブジェクト自体が何と呼ばれるのかを知らないと言っているため、それが手がかりでした。Pythonオブジェクトは自己参照型ではありません。それから、名前は名前空間に住んでいます。これはTCL / TKにあります。だから多分私の答えは役立つでしょう(しかしそれは私を助けました)

    jj = 123
    print eval( "'" + str(id(jj))+ "'")
    dir()を印刷する

166707048
['__builtins__'、 '__doc__'、 '__file__'、 '__name__'、 '__package__'、 'jj']

したがって、リストの最後に「jj」があります。

コードを次のように書き換えます。

    jj = 123
    print eval( "'" + str(id(jj))+ "'")
    dir()のxの場合:
        print id(eval(x))

161922920
['__builtins__'、 '__doc__'、 '__file__'、 '__name__'、 '__package__'、 'jj']
3077447796
136515736
3077408320
3077656800
136515736
161922920

この厄介なコードIDは、変数/オブジェクト/ whatever-you-pedantics-call-itの名前です。

だから、それはあります。「jj」のメモリアドレスは、グローバルネームスペースでディクショナリルックアップを実行するときと同じように、直接検索したときと同じです。これを行う関数を作成できると確信しています。variable / object / wypciがどの名前空間にあるか覚えておいてください。

QED。


6
ここでは、evalの2つのクレイジーな使い方があります。1つ目は次とまったく同じですprint id(jj)。2番目は単に名前を検索するだけで、を使用するとより簡単に実行できますvars()
Ned Batchelder 2013

2

多分私はこれを考えすぎているのですが…

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

すごい!これは私が探していたものです。おかげで@ rh0dium ... \ Nvariable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
Majdi

2
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

2

pypiにソリューションをアップロードしました。これは、C#のnameof関数と同等のものを定義するモジュールです。

呼び出されたフレームのバイトコード命令を繰り返し、渡された変数/属性の名前を取得します。名前が中に発見された.argreprLOAD関数の名前を次の手順。



1

ほとんどのオブジェクトには__name__属性がありません。(クラス、関数、モジュールにはありますが、それ以上の組み込み型はありますか?)

あなたは他に何を期待するprint(my_var.__name__)以外のprint("my_var")?文字列を直接使用できますか?

辞書を「スライス」できます。

def dict_slice(D, keys, default=None):
  return dict((k, D.get(k, default)) for k in keys)

print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})

または:

throw = object()  # sentinel
def dict_slice(D, keys, default=throw):
  def get(k):
    v = D.get(k, throw)
    if v is not throw:
      return v
    if default is throw:
      raise KeyError(k)
    return default
  return dict((k, get(k)) for k in keys)

2
+1が、名前が存在しないことはわかっていますが、なぜ誰もが「このようなもの」を文字通りに取るのですか?私は名前をハーコード化したくないので、あなたの解決策は問題を解決しません、余計に私は質問ですでに与えたdict解決策を行います。
e-satis 2010年

3
@ e-satis:locals()ですべてを使用するだけで問題が解決する場合、私はあなたが何を求めているのかわかりません。を呼び出しても大丈夫だと思うので、dictsliceを使用すると、複数の変数の名前と値のマッピングを一度に取得できるので、 some_func(var)からそれほど遠くないことを指摘しようとしました。some_func("var")

1

まあ、私は非常に同じ遭遇した必要性を数日前としていた変数の取得名前を指していたオブジェクト自体を。

そしてなぜそれがそんなに必要だったのですか?

つまり、Mayaのプラグインを作成していました。コアプラグインはC ++を使用して構築されていますが、GUIはPythonを介して描画されます(プロセッサに負荷をかけないため)。私はまだ、returnデフォルト以外のプラグインから複数の値を取得する方法がわからないMStatusため、Pythonでディクショナリを更新するには、変数の名前を渡して、GUIを実装するオブジェクトを指す必要がありました。プラグインにディクショナリ自体が含まれ、それを使用しMGlobal::executePythonCommand()Mayaのグローバルスコープからディクショナリを更新します。

それをするために私がしたことは次のようなものでした:

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

globals多くのキーが同じオブジェクトを指している可能性があるので、それは完璧な解決策ではないことを知っています。例:

a = foo()
b = a
b.name()
>>>b
or
>>>a

また、このアプローチはスレッドセーフではありません。私が間違っていたら訂正してください。

少なくともこのアプローチは、オブジェクト自体を指すグローバルスコープ内の変数の名前を取得し、内部で使用するために引数としてプラグインに渡すことで、私の問題を解決しました。

私はこれを試しましたがint(プリミティブ整数クラス)、問題はこれらのプリミティブクラスがバイパスされないことです(間違っている場合は、使用されている技術用語を修正してください)。あなたは、再実装することができint、次に行うint = fooが、a = 3対象になることはありませんfooが、プリミティブの。それを克服するa = foo(3)にはa.name()、仕事に取り掛かる必要があります。


1

Python 2.7以降では、辞書の理解が少し短くなります。可能であれば、トップの回答のように、eval(evalはevil)の代わりにgetattrを使用します。Selfは、あなたが見ているコンテキストを持つ任意のオブジェクトです。オブジェクトまたはlocals = locals()などにすることができます。

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

1

私は同様の問題に取り組んでいました。@ S.Lottは、「変数のリストがある場合、それらの名前を「発見」する意味は何ですか?」と述べました。そして、私の答えは、それが可能かどうか、そして何らかの理由で変数をタイプ別にリストにソートしたいかどうかを確認することです。とにかく、私の研究で私はこのスレッドに出くわし、私のソリューションは少し拡張されており、@ rlotunソリューションに基づいています。@unutbuはもう1つ、「このアイデアにはメリットがありますが、2つの変数名が同じ値(Trueなど)を参照している場合、意図しない変数名が返される可能性があることに注意してください。」この演習では真実だったので、可能性ごとに次のようなリスト内包表記を使用して対処しましたisClass = [i for i in isClass if i != 'item']。これがないと、「アイテム」が各リストに表示されます。

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

私がこれに関して取る問題は、名前がオブジェクトのプロパティではないということです。1つのオブジェクトに複数の名前を付けることも、名前を付けないこともできます。たとえばpi = pie、コードに追加した場合、isFloatリストに追加のエントリが表示されます。リストに追加tuple_1[0]した場合mixedDataTypes、コードに「1」が2回含まれていても、その名前は見つかりません(ただし、文字列のインターンにより、どちらも同じオブジェクトへの参照になります)。
Blckknght

1
@Blckknght ---同意します。これは、実際に行うことを意図していないことを実行するもう1つの方法です。私はそれが独特の結果をもたらすか、それが絶対的であるとは言いませんでした。これを行う際に、変数としてpi、およびe変数として使用すると、不要な出力が発生することがわかりましたmath。これは、両方がライブラリの一部であるためです。私にとってこれは、最終結果が完全ではない場合でも、それができるかどうかを確認するための練習でした。この言語についての私の学習では、本を通ることはこれまでしか行きません。私の意見では、本当にその言語を学びたいのなら、「もしも」をプレイして、あなたが思いついたものを見る必要があります。
Michael Swartz 2013

1

easydictを使うことができます

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

もう一つの例:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

1

python3では、この関数はスタックの最も外側の名前を取得します。

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

コードのどこでも便利です。逆スタックを走査して、最初の一致を探します。


0

これはおそらくひどい考えですが、rlotunの答えと同じようにありますが、より頻繁に正しい結果が返されます。

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

次のように呼び出します。

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

0

リストを取得して返す必要があります

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

0

変数の名前は返しませんが、グローバル変数から簡単に辞書を作成できます。

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

0

python-varnameあなたはそれを簡単に行うことができます。

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

免責事項:私はそのpython-varnameライブラリの作者です。


-1
>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

この方法で、多分 'a'または 'b'のvarnameを取得します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.