オブジェクトの属性を一覧表示する


330

クラスのインスタンスに存在する属性のリストを取得する方法はありますか?

class new_class():
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

a = new_class(2)
print(', '.join(a.SOMETHING))

望ましい結果は、「multi、str」が出力されることです。これで、スクリプトのさまざまな部分の現在の属性を確認できます。


75
Pythonのほぼ全員が、クラスにのような名前を付けていますNewClass。のような命名規則を使用すると、人々の期待に反する可能性がありますnew_class
マイクグラハム

人間が対話式でプログラムで使用できない場合でも、help()関数はクラス、関数、組み込み関数、モジュールなどに関する情報を取得するのに役立ちます
ytpillai


回答に「承認済み」のマークが付いていないのはなぜですか?
pfabri

回答:


295
>>> class new_class():
...   def __init__(self, number):
...     self.multi = int(number) * 2
...     self.str = str(number)
... 
>>> a = new_class(2)
>>> a.__dict__
{'multi': 4, 'str': '2'}
>>> a.__dict__.keys()
dict_keys(['multi', 'str'])

pprint役立ちます。


29
dictの使用法の問題がr / pythonに現れました。vars(a)はa .__ dict__と同等であると誰かが指摘しました
David

5
誰かが疑問に思っている場合に備えて、これはPython 2.7でも動作します
Ben Mordecai

8
具体的にpprint.pprint(a.__dict__)は、属性をきれいに印刷します。
smci 2016

1
もちろん、pprintPython 2.6では動作しません。
John Greene

3
これは、ユーザー定義クラスに対してのみ機能し、組み込みタイプまたは拡張タイプでは機能しないことに注意してください。
ivan_pozdeev 2017年

173
dir(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__

次に、タイプが何であるか、type()またはメソッドがであるかどうかをテストできますcallable()


dirは、オーバーロードされた属性get / setを持つクラスでより適切に機能しました
ogurets

dir(instance)は、おそらく興味のない多くのことをリストします
jciloa '25

これは、bostonsklearnからデータセットで使用可能なすべての属性を取得した唯一の関数でした。__dict__実際には5つの使用可能な属性があった
のに空でした


53

以前のすべての答えは正しいです。あなたが尋ねていることには3つのオプションがあります

  1. dir()

  2. vars()

  3. __dict__

>>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']
>>> vars(a)
{'multi': 4, 'str': '2'}
>>> a.__dict__
{'multi': 4, 'str': '2'}

1
vars(foo)リターンfoo.__dict__
ボリス

32
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'

もちろん、これはクラス定義のメソッドや属性を出力します。あなたは、変更することにより、「プライベート」メソッドを除外することができますi.startwith('__')i.startwith('_')


24

検査モジュールは、オブジェクトを検査する簡単な方法を提供します。

inspectモジュールは、モジュール、クラス、メソッド、関数、トレースバック、フレームオブジェクト、コードオブジェクトなどのライブオブジェクトに関する情報を取得するのに役立ついくつかの便利な関数を提供します。


を使用getmembers()すると、クラスのすべての属性とその値を確認できます。プライベート属性または保護属性を除外するには、を使用します.startswith('_')。メソッドや関数の使用を除外しますinspect.ismethod()か、inspect.isfunction()

import inspect


class NewClass(object):
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

    def func_1(self):
        pass


a = NewClass(2)

for i in inspect.getmembers(a):
    # Ignores anything starting with underscore 
    # (that is, private and protected attributes)
    if not i[0].startswith('_'):
        # Ignores methods
        if not inspect.ismethod(i[1]):
            print(i)

ご了承ください ismethod()i最初の要素は単なる文字列(その名前)なので、の2番目の要素で使用されることに。

Offtopic:使用キャメルケースクラス名のために。


13

を使用dir(your_object)して属性を取得し、getattr(your_object, your_object_attr)を取得し、値を取得できます

使用法 :

for att in dir(your_object):
    print (att, getattr(your_object,att))

これは、オブジェクトに__dict__がない場合に特に役立ちます。そうでない場合は、var(your_object)も試すことができます


11

属性の完全なリストを一覧表示するには、使用する必要があるとよく言われますdir()。ただし、一般的な信念に反しdir()て、すべての属性が引き出されるわけではないことに注意してください。たとえば、クラス自体からアクセスできても__name__、クラスのdir()リストに表示されない場合があります。dir()Python 2Python 3)のドキュメントから:

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

返されたリストから完全性の保証はありませんが、以下のような機能は、より完全になりがちdir()実装を含む多くの要因によって影響を受けることができる__dir__()方法を、またはカスタマイズ__getattr__()または__getattribute__()クラスまたはその両親のいずれかが。詳細については、提供されているリンクを参照してください。

def dirmore(instance):
    visible = dir(instance)
    visible += [a for a in set(dir(type)).difference(visible)
                if hasattr(instance, a)]
    return sorted(visible)

9

これは何のために使いますか?正確な意図を知らずに最良の答えを得るのは難しいかもしれません。

  • クラスのインスタンスを特定の方法で表示したい場合は、ほとんどの場合、手動で行う方が適切です。これには正確に必要なものが含まれ、不要なものは含まれず、順序は予測可能です。

    クラスのコンテンツを表示する方法を探している場合は、必要な属性を手動でフォーマットし、これをクラスの__str__または__repr__メソッドとして提供します。

  • オブジェクトがどのように機能するかを理解するために存在するメソッドなどについて知りたい場合は、を使用してくださいhelphelp(a)docstringに基づいてオブジェクトのクラスに関するフォーマットされた出力が表示されます。

  • dirオブジェクトのすべての属性をプログラムで取得するために存在します。(アクセス__dict__すると、同じようにグループ化しますが、自分では使用しません。)ただし、これには、必要なものが含まれていない場合や、不要なものが含まれている場合があります。それは信頼できず、人々は彼らが望むよりもずっと頻繁にそれを望んでいると思っています。

  • やや直交する注意点として、現時点ではPython 3のサポートはほとんどありません。実際のソフトウェアを作成することに興味がある場合は、numpy、lxml、Twisted、PIL、またはまだPython 3をサポートしておらず、すぐには計画されていない任意の数のWebフレームワークなどのサードパーティ製品が必要になります。2.6と3.xブランチの違いはわずかですが、ライブラリサポートの違いは非常に大きくなります。


4
5年後(現在)に指摘したいのですが、皆さんが言及しているすべてのサードパーティモジュールがpython3をサポートしていると思います。出典:python3wos.appspot.com
pzkpfw

8

それを行う方法は複数あります。

#! /usr/bin/env python3
#
# This demonstrates how to pick the attiributes of an object

class C(object) :

  def __init__ (self, name="q" ):
    self.q = name
    self.m = "y?"

c = C()

print ( dir(c) )

このコードを実行すると、以下が生成されます。

jeffs@jeff-desktop:~/skyset$ python3 attributes.py 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',      '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm', 'q']

jeffs@jeff-desktop:~/skyset$

2
なぜこの回答は反対投票されたのですか?デバッグのために、dirはかなりうまく機能します!
Dunatotatos 2017年

PrettyはPython 2.7.xで動作します。まさに私が欲しかったもの。
デビッドソンリマ

7

順番に実行されたpythonシェルスクリプトをご覧ください。ここでは、クラスの属性をカンマで区切られた文字列形式で取得します。

>>> class new_class():
...     def __init__(self, number):
...         self.multi = int(number)*2
...         self.str = str(number)
... 
>>> a = new_class(4)
>>> ",".join(a.__dict__.keys())
'str,multi'<br/>

私はpython 3.4を使用しています


そして、あなたが欲しいのであれば、リストだけがちょうど使用できますa.__dict__.keys()。ただし、オブジェクトに特定の属性があるかどうかを知りたい場合は、を使用できますhasattr
berna1111 2017年

4

これらの回答に加えて、任意の値の構造全体を実質的に吐き出すための関数(python 3)を含めます。dirプロパティ名の完全なリストを確立するために使用し、次にgetattr各名前で使用します。値のすべてのメンバーのタイプを表示し、可能な場合はメンバー全体も表示します。

import json

def get_info(obj):

  type_name = type(obj).__name__
  print('Value is of type {}!'.format(type_name))
  prop_names = dir(obj)

  for prop_name in prop_names:
    prop_val = getattr(obj, prop_name)
    prop_val_type_name = type(prop_val).__name__
    print('{} has property "{}" of type "{}"'.format(type_name, prop_name, prop_val_type_name))

    try:
      val_as_str = json.dumps([ prop_val ], indent=2)[1:-1]
      print('  Here\'s the {} value: {}'.format(prop_name, val_as_str))
    except:
      pass

これで、次のいずれかが洞察を与えるはずです。

get_info(None)
get_info('hello')

import numpy
get_info(numpy)
# ... etc.

うわー、それは宝石です!
pfabri

ええ、これは命の恩人でした。これがなぜこれらのリストを簡単にアンパックできなかったのかを理解できず、十分なタイプにタイプ「タプル」のプロパティ「スロット」があることを確認できませんでした。スロット値は次のとおりです。 「再試行」、「期限切れ」、「minttl」、「ttl」]
Mik R

3

オブジェクトの属性を取得する

class new_class():
    def __init__(self, number):
    self.multi = int(number) * 2
    self.str = str(number)

new_object = new_class(2)                
print(dir(new_object))                   #total list attributes of new_object
attr_value = new_object.__dict__         
print(attr_value)                        #Dictionary of attribute and value for new_class                   

for attr in attr_value:                  #attributes on  new_class
    print(attr)

出力

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__','__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']

{'multi': 4, 'str': '2'}

multi
str

1

使用前に記述したとおり、obj.__dict__一般的なケースを処理できますが、一部のクラスには__dict__属性がなく、使用されています__slots__(主にメモリ効率のため)。

これを行うためのより弾力的な方法の例:

class A(object):
    __slots__ = ('x', 'y', )
    def __init__(self, x, y):
        self.x = x
        self.y = y


class B(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y


def get_object_attrs(obj):
    try:
        return obj.__dict__
    except AttributeError:
        return {attr: getattr(obj, attr) for attr in obj.__slots__}


a = A(1,2)
b = B(1,2)
assert not hasattr(a, '__dict__')

print(get_object_attrs(a))
print(get_object_attrs(b))

このコードの出力:

{'x': 1, 'y': 2}
{'x': 1, 'y': 2}

注1:
Pythonは動的言語であり、このコードで場合によっては見落とされる可能性があるため、属性を取得しようとしているクラスを常に理解していることが重要です。

注2:
このコードは、クラス変数が提供されていないことを意味するインスタンス変数のみを出力します。例えば:

class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

print(A('/questions').__dict__)

コード出力:

{'path': '/questions'}

このコードはurlクラス属性を出力せず、必要なクラス属性を省略する場合があります。
属性がインスタンスメンバーであると考える場合がありますが、この例では表示されず、表示されません。


2
クラスは__dict__ and を持つことができる__slots__ので、おそらく辞書だけでなく両方を試してみたいと思います。
CZ

1
  • それを逃すので使用する__dict__か、vars 動作しません__slots__
  • を使用する__dict__と、基本クラスから外れるため__slots__ 機能しません__slots__
  • メソッドやプロパティなどのクラス属性とオブジェクト属性が含まれてdir いるため、を使用しても機能ません
  • を使用することvarsは、を使用することと同じ__dict__です。

これは私が持っている最高のものです:

from typing import Dict

def get_attrs( x : object ) -> Dict[str, object]:
    mro      = type( x ).mro()
    attrs    = { }
    has_dict = False
    sentinel = object()

    for klass in mro:
        for slot in getattr( klass, "__slots__", () ):
            v = getattr( x, slot, sentinel )

            if v is sentinel:
                continue

            if slot == "__dict__":
                assert not has_dict, "Multiple __dicts__?"
                attrs.update( v )
                has_dict = True
            else:
                attrs[slot] = v

    if not has_dict:
        attrs.update( getattr( x, "__dict__", { } ) )

    return attrs

この関数をspomeの単純なクラスに適用してみましょう:クラスC:def __init __(self):print( "created")i = 42なぜあなたのコードはそのようなクラスに空のリストを与えるのですか?また、( "mystr")get_attrsのためにした(0 = C()、その後get_attrs(O)が空である場合、私は意味)
GED

0
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]

大文字または単一の下線で始まるクラス属性名では機能しません。
fviktor 2016

0

次のPythonシェルスクリプトの実行を順に参照してください。クラスの作成からインスタンスのフィールド名の抽出までのソリューションが提供されます。

>>> class Details:
...       def __init__(self,name,age):
...           self.name=name
...           self.age =age
...       def show_details(self):
...           if self.name:
...              print "Name : ",self.name
...           else:
...              print "Name : ","_"
...           if self.age:
...              if self.age>0:
...                 print "Age  : ",self.age
...              else:
...                 print "Age can't be -ve"
...           else:
...              print "Age  : ","_"
... 
>>> my_details = Details("Rishikesh",24)
>>> 
>>> print my_details
<__main__.Details instance at 0x10e2e77e8>
>>> 
>>> print my_details.name
Rishikesh
>>> print my_details.age
24
>>> 
>>> my_details.show_details()
Name :  Rishikesh
Age  :  24
>>> 
>>> person1 = Details("",34)
>>> person1.name
''
>>> person1.age
34
>>> person1.show_details
<bound method Details.show_details of <__main__.Details instance at 0x10e2e7758>>
>>> 
>>> person1.show_details()
Name :  _
Age  :  34
>>>
>>> person2 = Details("Rob Pike",0)
>>> person2.name
'Rob Pike'
>>> 
>>> person2.age
0
>>> 
>>> person2.show_details()
Name :  Rob Pike
Age  :  _
>>> 
>>> person3 = Details("Rob Pike",-45)
>>> 
>>> person3.name
'Rob Pike'
>>> 
>>> person3.age
-45
>>> 
>>> person3.show_details()
Name :  Rob Pike
Age can't be -ve
>>>
>>> person3.__dict__
{'age': -45, 'name': 'Rob Pike'}
>>>
>>> person3.__dict__.keys()
['age', 'name']
>>>
>>> person3.__dict__.values()
[-45, 'Rob Pike']
>>>

また、各attributes.visitののcallabliltyを確認することができますstackoverflow.com/questions/1398022/...
hygull

-4

__attr__ インスタンスの属性のリストを提供します。

>>> import requests
>>> r=requests.get('http://www.google.com')
>>> r.__attrs__
['_content', 'status_code', 'headers', 'url', 'history', 'encoding', 'reason', 'cookies', 'elapsed', 'request']
>>> r.url
'http://www.google.com/'
>>>

常に機能するとは限りません。また、__attr__説明には書き込みます__attrs__が、コードでは使用します。どちらもうまくいかなかった(werkzeug.datastructures.FileStorage)
Jonas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.