[解決済み] 変数名から文字列への変換は?
質問
Pythonの変数名を文字列に変換したいのですが、どうすればよいですか?どのようなアイデアがありますか?
var = {}
print ??? # Would like to see 'var'
something_else = 3
print ??? # Would print 'something_else'
どのように解決するのですか?
TL;DR: 不可能です。最後の「結論」をご覧ください。
これが必要になる可能性のある使用シナリオがあります。私は、より良い方法や同じ機能を達成する方法がないと言っているわけではありません。
これは、エラー発生時、デバッグモード、および他の同様の状況で、辞書の任意のリストを「ダンプ」するために有用でしょう。
必要とされるのは、逆方向の
eval()
関数の逆です。
get_indentifier_name_missing_function()
は、識別子名('変数'、'辞書'など)を引数として受け取り、識別子の名前を含む文字列を返します。 文字列を返します。
以下のような現状を考えてみましょう。
random_function(argument_data)
識別子名('function'、'variable'、'dictionary'など)を渡す場合
argument_data
を
random_function()
(別の識別子名) を渡すと、実際に識別子 (例えば
<argument_data object at 0xb1ce10>
) を別の識別子 (例えば
<function random_function at 0xafff78>
):
<function random_function at 0xafff78>(<argument_data object at 0xb1ce10>)
私の理解では、関数に渡されるのはメモリアドレスのみです。
<function at 0xafff78>(<object at 0xb1ce10>)
そのため、文字列を引数として
random_function()
に文字列を渡して、その関数が引数の識別子の名前を持つようにする必要があります。
random_function('argument_data')
random_function()の内部
def random_function(first_argument):
の場合、すでに提供されている文字列
'argument_data'
にします。
-
識別子名」として機能する (表示、ログ、文字列分割/concat などのために)
-
をフィードします。
eval()
関数に送り、実際の識別子への参照、つまり実際のデータへの参照を取得します。print("Currently working on", first_argument) some_internal_var = eval(first_argument) print("here comes the data: " + str(some_internal_var))
残念ながら、これはすべてのケースでうまくいくわけではありません。うまくいくのは
random_function()
を解決できる場合のみです。
'argument_data'
の文字列を実際の識別子に解決することができます。すなわち、もし
argument_data
の中に識別子の名前があれば
random_function()
の名前空間を使用します。
これは常にそうであるとは限りません。
# main1.py
import some_module1
argument_data = 'my data'
some_module1.random_function('argument_data')
# some_module1.py
def random_function(first_argument):
print("Currently working on", first_argument)
some_internal_var = eval(first_argument)
print("here comes the data: " + str(some_internal_var))
######
期待される結果は、次のようになります。
Currently working on: argument_data
here comes the data: my data
なぜなら
argument_data
の識別子名は
random_function()
の名前空間で利用できない場合は、代わりにこれが返されます。
Currently working on argument_data
Traceback (most recent call last):
File "~/main1.py", line 6, in <module>
some_module1.random_function('argument_data')
File "~/some_module1.py", line 4, in random_function
some_internal_var = eval(first_argument)
File "<string>", line 1, in <module>
NameError: name 'argument_data' is not defined
では、仮の使い方として
get_indentifier_name_missing_function()
を使うと、上記のように動作します。
Python 3.0のダミーのコードです。.
# main2.py
import some_module2
some_dictionary_1 = { 'definition_1':'text_1',
'definition_2':'text_2',
'etc':'etc.' }
some_other_dictionary_2 = { 'key_3':'value_3',
'key_4':'value_4',
'etc':'etc.' }
#
# more such stuff
#
some_other_dictionary_n = { 'random_n':'random_n',
'etc':'etc.' }
for each_one_of_my_dictionaries in ( some_dictionary_1,
some_other_dictionary_2,
...,
some_other_dictionary_n ):
some_module2.some_function(each_one_of_my_dictionaries)
# some_module2.py
def some_function(a_dictionary_object):
for _key, _value in a_dictionary_object.items():
print( get_indentifier_name_missing_function(a_dictionary_object) +
" " +
str(_key) +
" = " +
str(_value) )
######
期待される結果は、次のようになります。
some_dictionary_1 definition_1 = text_1
some_dictionary_1 definition_2 = text_2
some_dictionary_1 etc = etc.
some_other_dictionary_2 key_3 = value_3
some_other_dictionary_2 key_4 = value_4
some_other_dictionary_2 etc = etc.
......
......
......
some_other_dictionary_n random_n = random_n
some_other_dictionary_n etc = etc.
残念ながら
get_indentifier_name_missing_function()
では、「元の」識別子の名前 (
some_dictionary_
,
some_other_dictionary_2
,
some_other_dictionary_n
). それは
a_dictionary_object
という識別子名だけが表示されます。
したがって、本当の結果はむしろ
a_dictionary_object definition_1 = text_1
a_dictionary_object definition_2 = text_2
a_dictionary_object etc = etc.
a_dictionary_object key_3 = value_3
a_dictionary_object key_4 = value_4
a_dictionary_object etc = etc.
......
......
......
a_dictionary_object random_n = random_n
a_dictionary_object etc = etc.
では、逆に
eval()
関数はこの場合、それほど有用ではないでしょう。
現状では、このようにする必要があるでしょう。
# main2.py same as above, except:
for each_one_of_my_dictionaries_names in ( 'some_dictionary_1',
'some_other_dictionary_2',
'...',
'some_other_dictionary_n' ):
some_module2.some_function( { each_one_of_my_dictionaries_names :
eval(each_one_of_my_dictionaries_names) } )
# some_module2.py
def some_function(a_dictionary_name_object_container):
for _dictionary_name, _dictionary_object in a_dictionary_name_object_container.items():
for _key, _value in _dictionary_object.items():
print( str(_dictionary_name) +
" " +
str(_key) +
" = " +
str(_value) )
######
結論から言うと
- Pythonは関数への引数としてメモリアドレスのみを渡します。
-
識別子の名前を表す文字列は、実際の識別子を参照するためにのみ
eval()
関数で実際の識別子を参照することができます。 -
の仮想的な逆で
eval()
関数は、識別子の名前が呼び出し側のコードから直接見えない場合には、 役に立ちません。たとえば、呼び出された関数の内部などです。 -
現在、関数に渡す必要があるのは
- 識別子の名前を表す文字列
- 実際の識別子(メモリアドレス)
を渡すことで、これを実現できます。
'string'
と
eval('string')
を同時に呼び出すことができます。これは、任意の関数、モジュール、名前空間にわたってこの卵鶏問題を解決する、コーナーケースのソリューションを使用せずに、最も「一般的」な方法だと思います。唯一の欠点は
eval()
という関数があり、これは簡単に安全でないコードにつながる可能性があります。を送り込まないように注意する必要があります。
eval()
関数に何もかも、特にフィルタリングされていない外部入力データを与えないように注意する必要があります。
関連
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み] 文字列をfloatやintにパースするにはどうしたらいいですか?
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] モジュールの関数名(文字列)を使って、モジュールの関数を呼び出す。
-
[解決済み] 文字列が空かどうかを確認する方法は?
-
[解決済み] Pythonで整数から文字列に変換する
-
[解決済み】Bashでファイル名と拡張子を抽出する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 「is" 演算子が整数に対して予期せぬ振る舞いをする。
-
[解決済み] DataFrameの文字列、dtypeがobjectの場合
-
[解決済み] PythonでファイルのMD5チェックサムを計算するには?重複
-
[解決済み] PILからopenCVフォーマットへの変換
-
[解決済み] バブルソートの宿題
-
[解決済み] django.db.migrations.exceptions.InconsistentMigrationHistory
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] あるオブジェクトが数であるかどうかを確認する、最もパイソン的な方法は何でしょうか?
-
[解決済み] Pythonで、ウェブサイトが404か200かを確認するためにurllibをどのように使用しますか?
-
[解決済み] Alembicアップグレードスクリプトでインサートやアップデートを実行するにはどうすればよいですか?