🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

3708閲覧

Pythonでインスタンス生成時に代入先の変数名を取得する方法

tas0g

総合スコア9

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2019/11/18 02:21

編集2019/11/18 02:47

インスタンス生成時に代入先の変数名の取得方法

私はPythonの使われている、オープンソースのプログラミング言語の勉強をしています。

Pythonにおいて、生成されるインスタンスの代入先の変数名を文字列で取得したいです。
もし、これを実現する方法や代案が存在すれば教えてほしいです。

コードの例

具体的に実現したいコードを示します

Python

1# 現在のコードはこのようになっています 2class ManualVariableNamed: 3 def __init__(self, name): 4 self.variable_name = name # ここに変数名の文字列を格納したいです 5 6def main(): 7 x = ManualVariableNamed(name='x') # このように文字列を与えることが冗長だと感じます 8 print(x.variable_name) # => 'x' 9 10 11# 次に、実現したいコードの例を示します 12# インスタンス生成時の変数名を自動で取得できるクラスを考えます 13class GetSelfVariableNameClass: 14 def __init__(self): 15 self.variable_name = get_variable_name(self) # 例えばこのような具合です 16 17def main(): 18 y = GetSelfVariableNameClass() 19 print(y.variable_name) # => 'y'

試したこと

現在のスコープの変数名一覧はglobals()locals()で取得できます。
これを用いてid(self)と一致する変数を探すことを考えました。
しかし、①代入評価前の変数を、②違うスコープから見つける方法がありません。
イニシャライザの引数で現在のスコープを明示的に与えることはしたくありません。

こちらの記事では Qiita:変数の変数名を文字列で取得する 方法が紹介されています。
しかし、私の実現したい事は、これでは解決できませんでした。

仕様レベルでの話でもいいので、何か少しでもヒントがあれば教えてください。
この実現が不可能であれば、その根拠を教えてもらえると助かります。よろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/11/18 02:27

「Pythonの使われている、オープンソースのプログラミング言語の勉強をしています。」とありますが、プログラミング言語はPythonそのものではないのですか?
tas0g

2019/11/18 02:30

説明不足でした。TVMというプロジェクトに含まれる、プログラミング言語(Relay IR)とそのコンパイラについて勉強しています。このコンパイラは一部にPythonが含まれています。
guest

回答4

0

ベストアンサー

  • 直感的には無理では? と思います。言語仕様上、まったく想定されていない動作なのです。
  • 無理やりできる方法があったとして(呼び出し元の構文情報を渡すとか)、やるべきではないと感じます。
  • 次善の策としてlocals()ドキュメント)を渡して書き換えるという発想が出てくるかもしれませんが、これは書き換え不可能ですからできません。
  • 名前空間の代わりに使う辞書を自分で作れば、↑相当の処理は可能でしょう。こんな感じです。できるけど何か利点はあるかなぁ・・・静的解析ツールなどの支援もこれだと受けられないでしょう。

python

1 2class GetSelfVariableNameClass: 3 # variable_name = None # クラス変数にしているのはたぶん意図と違うから消しておきますよ 4 def __init__(self, name, names): 5 self.variable_name = name 6 names[name] = self 7 8def main(): 9 names = dict() 10 GetSelfVariableNameClass("y", names) 11 # 以後ローカル変数yを書く代わりにnames["y"]と書くことにする 12 13 print(names["y"].variable_name) # => 'y' 14

投稿2019/11/18 02:45

編集2019/11/18 02:47
hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tas0g

2019/11/18 02:49

(クラス変数に対するコードのミスは修正しました) やはり、言語使用上は想定されていない使い方ですよね。 変数をディクショナリに格納する方法は、直接の解決でないですが、ヒントになりそうです。 ありがとうございます。
guest

0

Pythonにおいて、生成されるインスタンスの代入先の変数名を文字列で取得したいです。

そもそも論として、このような動作が必要な理由がわかりません。

仮にできたとしても、「ローカル変数の名前を変えるだけで動作が変わってしまうオブジェクト」は、筋が悪すぎます(呼び出した環境と密結合になってしまいます)。そして、ローカル変数はまさにローカルなもので外部とのI/Fに使われることもありませんので、呼ばれたコードから知ったところで使い道もないはずです。

投稿2019/11/18 02:35

maisumakun

総合スコア145963

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tas0g

2019/11/18 03:09 編集

回答ありがとうございます。 説明に語弊がありました。補足させてもらいます。 最初にローカル変数にインスタンスを代入したときの変数名を、変数名が変わっても保持し続けることを想定しています。例えば以下のような動作を想定しています。 ```Python y = GetSelfVariableNameClass() print(y.variable_name) # => 'y' z = y print(z.variable_name) # => 'y' ``` また、おっしゃる通り、本質的にローカル変数名を保持している意味はありません。しかし、デバッグの都合から、オブジェクトに識別名を付与したいケースあります。 例えば、Tensorflowというディープラーニングのフレームワークには tf.constant という、定数オブジェクトを生成するメソッドがあります。 https://www.tensorflow.org/api_docs/python/tf/constant デフォルトで`name='Const'`とされていますが、慣例的にローカル変数名をつけることがあります。 これは、動作には全く作用がありませんが、デバッグを容易にします。 私はこのような状況を想定して、質問していました。
guest

0

インスタンス化した時点ではローカル変数はまだありません。
例えば
i = j = obj()
とした場合は、なにを格納しますか?
return obj()
とか。

というわけで無理です。

投稿2019/11/29 09:04

編集2019/11/29 11:59
Q71

総合スコア995

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

vars() で変数辞書一覧が取れるけど、そういう話ではない?
vars関数の引数には変数辞書を取りたいオブジェクトを指定できます。
引数を指定しないと locals() でローカル変数辞書が見えます。
他に、globals() でグローバル変数辞書が見えます。・

python

1class SampleClass: 2 def __init__(self): 3 self.x = 123 4 5def main(): 6 y = SampleClass() 7 print(vars(y)) 8 print(vars()) 9 10if __name__ == '__main__': 11 main()

実行結果:

{'x': 123} {'y': <__main__.SampleClass object at 0x6ffffd106a0>}

投稿2019/11/29 08:55

編集2019/11/29 09:07
shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiracamus

2019/11/29 09:54 編集

インスタンス生成中に、その後に代入されるであろう変数名を取得したいということですか・・・ 未来予想は無理ですねぇ・・・ 変数に代入せずに使い捨てることもあるだろうし・・・ 生成した関数から復帰すると変数名/変数辞書もなくなってしまうし・・・ 関数オブジェクトを渡して、逆アセンブルして STORE命令を捜しますか・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問