Pythonでオブジェクトのプロパティを列挙する方法は?


133

IC#はリフレクションを介して行います。JavaScriptでは、次のように簡単です。

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

Pythonでそれを行う方法?



3
この質問は誤称です。ほとんどの回答は、メンバーの列挙に関するものです。プロパティを列挙する方法、つまりで飾られたクラスのメンバーを探していました@property
Tomasz Gandor

回答:


153
for property, value in vars(theObject).iteritems():
    print property, ": ", value

一部のまれなケースでは__slots__プロパティがあることに注意してください__dict__。そのようなクラスにはがないことがよくあります。


1
値を変更するにはどうすればよいですか?JavaScriptでできること:object [property] = newValue。Pythonでそれを行う方法?
Jader Dias、

39
代わりにsetattr()を使用してください。
ネルソン

1
@ネルソンなぜそれがより良い選択肢なのか、詳しく説明していただけませんか?それはただ短いですか、それとも追加の考慮事項がありますか?
WhyNotHugo

8
@Hugo:まず「Pythonic」なので、言い換えると、コミュニティの大多数が期待する構文です。他の構文では、コードを読んでいる人を不必要に一時停止する可能性があります。次に、いくつかの型はセッターを実装し__setattr__()ます。ディクショナリに直接値を設定すると、オブジェクトのセッター(またはその親)がバイパスされます。Pythonでは、属性の設定(衛生など)中に目に見えるものよりも多くのことがバックグラウンドで発生しているsetattr()ことがよくあります。これを使用すると、見落とさないようにしたり、明示的に自分で処理したりする必要があります。
Michael Ekoka 2014

3
@ Hi-Angel うまくいきました。ただし、機能していないのは、Pythonの動的オブジェクトメンバーと周囲のステータスの間にある、先入観と仮定の集合です。静的メンバー(つまり、そのオブジェクトに登録されているオブジェクト属性とメソッド)vars()のみを返します。動的メンバー(つまり、オブジェクトのメソッドまたは同様のマジックによって動的に定義されたオブジェクト属性およびメソッド)返しませほとんどの場合、目的のプロパティは動的に定義されるため、またはで使用できません。__dict____getattr__()file.ImplementationNamevars()dir()
セシルカレー

69

を参照してくださいinspect.getmembers(object[, predicate])

オブジェクトのすべてのメンバーを、名前でソートされた(名前、値)のペアのリストで返します。オプションの述語引数が指定されている場合、述語が真の値を返すメンバーのみが含まれます。

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

ええ、この答えは素晴らしいです。これまでにこのモジュールを使用したことはありません。getmembers()は、dir(object)の結果を歩くだけで実装されます。
ネルソン

これがdictにアクセスするよりも優れている理由を詳しく説明できますか?Pythonのドキュメントはあまり役に立ちません。特に、通常はattributes代わりにこの用語を使用しているためですmembers(2つの間に違いはありますか?)。彼らは、一貫性を持たせるために、Python 3.0で名前を修正することができました。
nikow 2009

おっと、つまり__dict__、申し訳ありません。
nikow 2009

4
@nikow:inspect.getmembers()は、内部の詳細が変更されても機能し続けることが保証されています。
GeorgSchölly2009

3
@NicholasKnight は、(A)動的クラス属性メタクラス属性を含み、(B)渡された述語と一致しないメンバーを除外するという(ほとんど無視できる)副次的利点でinspect.getmembers()ラップdir()ますあくびね?可能なすべてのオブジェクトタイプを一般的にサポートするサードパーティライブラリに適しています。ただし、標準的な使用例では、絶対に十分です。 inspect.getmembers()dir()
セシルカレー

66

dir()簡単な方法です。こちらをご覧ください:

Pythonイントロスペクションのガイド


2
Pythonのドキュメントから注意すべき点は、dir()は主にインタラクティブなプロンプトで使用するための便宜として提供されるため、厳密または一貫して定義された名前のセットを提供するよりも、興味深い名前のセットを提供しようとすることです。その詳細な動作はリリースによって異なる場合があります。たとえば、引数がクラスの場合、メタクラス属性は結果リストに含まれません。
スカイラー、2015年

1
この回答は、CLIでスクラッチ作業を行う場合に最適です。

15年間のpython(これまでフルタイムの仕事ではありませんでした)と私はまだdir()ありがとうを忘れています。
Abhishek Dujari

14

__dict__オブジェクトのプロパティは、他のすべての定義済みプロパティの辞書です。Pythonクラスはgetattr をオーバーライドし、プロパティのように見えるがにはないものを作成できることに注意してください__dict__。また、組み込み機能がありますvars()し、dir()微妙な方法で異なっています。そして、いくつかの珍しいクラスで__slots__置き換えることができ__dict__ます。

Pythonではオブジェクトは複雑です。__dict__リフレクションスタイルのプログラミングを始めるのに最適な場所です。dir()対話型シェルでハッキングしている場合に開始する場所です。


print vars.__doc__ことを示しているWith an argument, equivalent to object.__dict__ので、微妙な違いは何でしょうか?
sancho.s ReinstateMonicaCellio 2014


10

すべてのプロパティの反映を探しているなら、上記の答えは素晴らしいです。

辞書のキー(Pythonの「オブジェクト」とは異なります)を取得するだけの場合は、次を使用します。

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

1
それは私の答えですが、受け入れられるべき答えではないと思います。オブジェクトのキーは、クラスのオブジェクトインスタンスのプロパティとは異なります。これらは別々に(アクセスしたobj['key']obj.property)との質問は、オブジェクトのプロパティについてでした。2つの間で簡単に混乱するので、ここに私の回答を示します。
MrE 2018

私は実際にこの答えを削除することをお勧めします。
Ente、

上記のように、たとえばJavascriptまたはC#から来た人々は、これら2つの概念に違いがないため、用語によって混乱しやすくなります。Pythonを学び、キーにアクセスしようとする人は、「プロパティ」を検索してここに到達する可能性が非常に高いため、なぜそれが属していると思いますか。
MrE、

そして、あなたは正しいですが、要点を逃してください:他の言語(JSを取る)では、オブジェクトと辞書の間に区別はありません。OPは、C#からの質問です。この回答は間違っていますが、11の賛成票を得ました。厳密なpythonの用語で調べた場合、技術的に正しい回答ではない(私が指摘しているように)にもかかわらず、ここに上陸した人々は役に立つと証明しています。私はそれをさらに明確にするために編集します。
MrE、

5

これは他の回答で完全にカバーされていますが、私はそれを明確にします。オブジェクトは、クラス属性と静的および動的インスタンス属性を持つことができます。

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasis静的でdynoあり、動的であり(プロパティデコレータを参照)classy、クラス属性です。単に行う__dict__vars、静的なもののみを取得する場合。

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

したがって、他のユーザー__dict__がすべて(およびそれ以上)を取得できるようにしたい場合。これには、魔法のメソッドと属性、および通常のバインドメソッドが含まれます。だからそれらを避けましょう:

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

typeプロパティ飾ら方法(動的属性)と呼ばれる、あなたの戻り値の種類ではなくなりますmethod。これを証明するために、jsonで文字列化します。

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

それがクラッシュした方法だったとしたら。

TL; DR。extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}3つすべてを呼び出すようにしてください。ただし、メソッドや魔法は必要ありません。

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