質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.51%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

11821閲覧

Python3でインスタンス名を取得する方法

Justmeaning

総合スコア13

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2017/09/22 06:11

編集2017/09/22 07:20

データベースの内容をリストなどに格納して、ある条件に該当するものを条件文で抜粋する、ということがやりたいです。
例えば、

Python

1class Vegetable: 2 def __init__(self, weight, color, price): 3 self.weight = weight 4 self.color = color 5 self.price = price 6carrot = Vegetable(150, "orange", 50) 7paprika_yellow = Vegetable(180, "yellow", 80) 8paprika_red = Vegetable(180, "red", 80) 9paprika_orange = Vegetable(180, "orange", 80) 10cucumber = Vegetable(100, "green", 20) 11cabbage = Vegetable(1200, "green", 390)

のような感じで作られたインスタンス全てに関して、

python

1for vegetable in vegetables: 2 if {instance_name}.color="green": 3 print({インスタンス名})

というようなことをしたいのですが、生成したインスタンスをうまくまとめるいい方法が思いつかず、さらに「python インスタンス名を取得」で検索しても方法が出てこないので現在は上記のクラスの引数にself.nameを追加して

python

1vegetables = [carrot, paprika_yellow, paprika_red, paprika_orange, cucumber, cabbage] 2 3上記for: 4 print(vegetable.name)

としています。二度手間感が満載なのと、拡張性がないため上記のコードを改修したいです。

1)インスタンス名自体を取得する方法、もしくは上記の例で格納するのにより適切な型を教えてください

2)上記の例で生成したインスタンス名を一度に取得する方法はないでしょうか。ない場合、1つのオブジェクト、リスト、辞書などにまとめるいい方法はあるでしょうか。

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

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

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

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

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

guest

回答2

0

ベストアンサー

あまりよい実装ではないかもしれませんが、質問の内容を実現するとした場合、下記のような感じでしょうか。

python

1class Vegetable: 2 def __init__(self, weight, color, price): 3 self.weight = weight 4 self.color = color 5 self.price = price 6 7carrot = Vegetable(150, "orange", 50) 8paprika_yellow = Vegetable(180, "yellow", 80) 9paprika_red = Vegetable(180, "red", 80) 10paprika_orange = Vegetable(180, "orange", 80) 11cucumber = Vegetable(100, "green", 20) 12cabbage = Vegetable(1200, "green", 390) 13 14vegetables = {k: v for k, v in locals().items() if type(v).__name__ == 'Vegetable'} 15 16for vegetable in vegetables: 17 if eval(vegetable).color == 'green': 18 print(vegetable)

インスタンス名は変数名としての扱いかと思いますので、
あまりそれ自体を利用するということはしない方がよいのではないかと思います。
例えばself.nameを追加した場合、インスタンスの配列として保持する形ではいかがでしょうか。
この場合は、名前をユニークにする必要がないため、同じ"paprika"でも複数定義できる、といったことも考えられます。

Python

1class Vegetable: 2 def __init__(self, name, weight, color, price): 3 self.name = name 4 self.weight = weight 5 self.color = color 6 self.price = price 7 8vegetables = [ 9 Vegetable("carrot", 150, "orange", 50), 10 Vegetable("paprika", 180, "yellow", 80), 11 Vegetable("paprika", 180, "red", 80), 12 Vegetable("paprika", 180, "orange", 80), 13 Vegetable("cucumber", 100, "green", 20), 14 Vegetable("cabbage", 1200, "green", 390), 15] 16 17for vegetable in vegetables: 18 if vegetable.color == 'green': 19 print(vegetable.name)

投稿2017/09/22 07:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Justmeaning

2017/09/22 07:38

なるほど、確かにクラス名で探すという方法もありますね。 正直なところ、このpaprikaの様な違うバージョンのものという扱いにも困っていたので、2番目の解決例がちょうど目的に合致しました。2番目の方法で実装させていただきます。 回答ありがとうございました。
guest

0

インスタンスじゃなくてただのタプルだったり質問の内容がよく飲み込めていないのですが、そもそもこういった集合の性質を持つインスタンスたちがまとまらずにそれぞれ転がっている状態がおかしいように思えます。

最初からリストなり辞書なに格納するだけで済む話だと思いますが。。。

python

1class Vegetable(object): 2 def __init__(self, weight, color, price): 3 self.weight = weight 4 self.color = color 5 self.price = price 6 7vegetables = { 8 'carrot': (150, "orange", 50), 9 'paprika_yellow': (180, "yellow", 80), 10 'paprika_red': (180, "red", 80), 11 'paprika_orange': (180, "orange", 80), 12 'cucumber': (100, "green", 20), 13 'cabbage': (1200, "green", 390), 14} 15 16vegetable_instances = {k: Vegetable(*v) for k, v in vegetables.items()} 17for k, v in vegetable_instances.items(): 18 print('{} is: {}'.format(k, v.color))

どうしても自分の居るスコープに居る Vegetable のインスタンスを探したいのであれば、dir() 関数と、isinstance() 関数 を組み合わせて以下のように取り出すこともできます。

python

1carrot = Vegetable(150, "orange", 50) 2paprika_yellow = Vegetable(180, "yellow", 80) 3paprika_red = Vegetable(180, "red", 80) 4paprika_orange = Vegetable(180, "orange", 80) 5cucumber = Vegetable(100, "green", 20) 6cabbage = Vegetable(1200, "green", 390) 7 8for obj in dir(): 9 if isinstance(eval(obj), Vegetable): 10 print('{} is {}'.format(obj, eval(obj).color))

ちょっと正気じゃないですね。。

投稿2017/09/22 07:03

編集2017/09/22 07:36
miyahan

総合スコア3095

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

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

Justmeaning

2017/09/22 07:30

回答ありがとうございました。 インスタンス生成がタプルになっていたのはミスです。すみません。 書いていただいたコードの上の方のコードが、実行すると定義エラーが出てしまいます。 Vegetable(*v) の部分が分からないのですが、これは何を意味されているんでしょうか。 また、辞書型での格納も考えたのですが、 carrot.colorやcabbage.priceの様に出す方法がわからず、辞書型は使いませんでした。 Pythonの辞書型はクラスの様な各項目の名前での指定はできるのでしょうか。
miyahan

2017/09/22 07:54

`*v` はアンパックというテクニックで、今回のようにタプルの中身を渡したいとき、Vegetable(v[0], v[1], v[2]) とやるのは面倒ですが、Vegetable(*v) とすることで v の中身を展開して渡すことが出来ます。 --- 上記のサンプルコードでは、辞書の "値" として Vegetable のインスタンスを格納しています。そのため、例えば carrot の color は `vegetable_instances['carrot'].color` で取り出せます。
Justmeaning

2017/09/22 08:25

アンパック知りませんでした。便利ですね! そういう方法で取り出すのですね。勉強になりました、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問