199

I C# we do it through reflection. In Javascript it is simple as:

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

How to do it in Python?

2
  • 1
    linking this: How do you get list of methods in a python class? Commented Apr 25, 2012 at 10:32
  • 10
    Please note that this question is a misnomer. Most answers are about enumerating members. I was looking for a way to enumerate properties, i.e. members of a class decorated with @property. Commented May 13, 2019 at 4:18

8 Answers 8

224
for property, value in vars(theObject).items(): print(property, ":", value) 

Be aware that in some rare cases there's a __slots__ property, such classes often have no __dict__.

Sign up to request clarification or add additional context in comments.

11 Comments

now how to change the value? in Javascript you could do: object[property] = newValue. How to do it in Python?
@Nelson Could you elaborate why that's a better option? Is it just shorter, or are there additional considerations?
@Hugo: First because it's "pythonic", in other words that's the syntax a large majority of the community is expecting to see. The other syntax would likely unnecessarily give pause to anyone reading your code. Second, some types implement a setter __setattr__(). Setting values directly on the dictionary bypasses the object's setter (and/or its parents'). It's quite common in python that more things than meet the eye are happening in the background during attribute setting (e.g. sanitation), using setattr() ensures that you don't miss out, or are forced to handle them explicitly yourself.
@Hi-Angel That does work. What isn't working, however, is the constellation of preconceptions and assumptions you have surrounding status versus dynamic object members in Python. vars() only returns static members (i.e., object attributes and methods registered with that object's __dict__). It does not return dynamic members (i.e., object attributes and methods dynamically defined by that object's __getattr__() method or similar magic). In all likelihood, your desired file.ImplementationName property is defined dynamically and hence not available to vars() or dir().
@CecilCurry dude, while I appreciate your enlightening comment, I don't appreciate your sarcasm. What you just said is neither obvious, nor easy to find unless one knows language internals enough to not ask it here. It ought to be mentioned in the answer.
|
97

dir() is the simple way. See here:

Guide To Python Introspection

1 Comment

Something to note from the Python docs, because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class.
77

See inspect.getmembers(object[, predicate]).

Return all the members of an object in a list of (name, value) pairs sorted by name. If the optional predicate argument is supplied, only members for which the predicate returns a true value are included.

>>> [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'] >>> 

7 Comments

Yeah, this answer is great; never used this module before. getmembers() is implemented by just walking the results of dir(object), btw.
Can you elaborate why this is better than accessing dict? The Python documentation is less than helpful, especially because normally it uses the term attributes instead of members (is there any difference between the two?). They could have fixed the name in Python 3.0 to make it consistent.
Oops, meant __dict__, sorry.
@nikow: inspect.getmembers() is guaranteed to keep working even if the internal details change.
@NicholasKnight inspect.getmembers() wraps dir() with the (mostly negligible) side benefits of (A) including dynamic class attributes and metaclass attributes and (B) excluding members not matching the passed predicate. Yawn, right? inspect.getmembers() is appropriate for third-party libraries generically supporting all possible object types. For standard use cases, however, dir() absolutely suffices.
|
22

The __dict__ property of the object is a dictionary of all its other defined properties. Note that Python classes can override getattr and make things that look like properties but are not in__dict__. There's also the builtin functions vars() and dir() which are different in subtle ways. And __slots__ can replace __dict__ in some unusual classes.

Objects are complicated in Python. __dict__ is the right place to start for reflection-style programming. dir() is the place to start if you're hacking around in an interactive shell.

1 Comment

print vars.__doc__ indicates that With an argument, equivalent to object.__dict__ So what would the subtle differences be?
18

for one-liners:

print vars(theObject) 

Comments

14

If you're looking for reflection of all properties, the answers above are great.

If you're simply looking to get the keys of a dictionary (which is different from an 'object' in Python), use

my_dict.keys()

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

4 Comments

even though it's my answer, I don't think it should be the accepted answer: the keys of an object are different from the property of an object instance of a class. They're accessed differently (obj['key'] vs. obj.property) and the question was about object properties. I put my answer here because there is easy confusion between the two.
I would actually suggest removing this answer.
As stated above, people coming from Javascript or C# for example are easily confused by the terminology as there is no difference between those 2 concepts. People learning python and trying to access keys are very likely to search for 'properties' and end up here, hence why I think it belongs.
and you are right, but miss the point: in other languages (take JS) there is no distinction between object and dictionary. The OP comes from C# asking the question. This answer, although wrong, got 11 upvotes, proof that people who land here find it useful, even though it is not technically the right answer (as I point out) to the question when looking at it in strict python lingo. I'll edit to make it even more crystal clear.
13

This is totally covered by the other answers, but I'll make it explicit. An object may have class attributes and static and dynamic instance attributes.

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

stasis is static, dyno is dynamic (cf. property decorator) and classy is a class attribute. If we simply do __dict__ or vars we will only get the static one.

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

So if we want the others __dict__ will get everything (and more). This includes magic methods and attributes and normal bound methods. So lets avoid those:

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} 

The type called with a property decorated method (a dynamic attribute) will give you the type of the returned value, not method. To prove this let's json stringify it:

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

Had it been a method it would have crashed.

TL;DR. try calling extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'} for all three, but not methods nor magic.

Comments

6

I think it's worth showing the difference between the various options mentioned - often a picture is worth a thousand words.

>>> from pprint import pprint >>> import inspect >>> >>> class a(): x = 1 # static class member def __init__(self): self.y = 2 # static instance member @property def dyn_prop(self): # dynamic property print('DYNPROP WAS HERE') return 3 def test(self): # function member pass @classmethod def myclassmethod(cls): # class method; static methods behave the same pass >>> i = a() >>> pprint(i.__dict__) {'y': 2} >>> pprint(vars(i)) {'y': 2} >>> pprint(dir(i)) ['__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__', 'dyn_prop', 'myclassmethod', 'test', 'x', 'y'] >>> pprint(inspect.getmembers(i)) DYNPROP WAS HERE [('__class__', <class '__main__.a'>), ('__delattr__', <method-wrapper '__delattr__' of a object at 0x000001CB891BC7F0>), ('__dict__', {'y': 2}), ('__dir__', <built-in method __dir__ of a object at 0x000001CB891BC7F0>), ('__doc__', None), ('__eq__', <method-wrapper '__eq__' of a object at 0x000001CB891BC7F0>), ('__format__', <built-in method __format__ of a object at 0x000001CB891BC7F0>), ('__ge__', <method-wrapper '__ge__' of a object at 0x000001CB891BC7F0>), ('__getattribute__', <method-wrapper '__getattribute__' of a object at 0x000001CB891BC7F0>), ('__gt__', <method-wrapper '__gt__' of a object at 0x000001CB891BC7F0>), ('__hash__', <method-wrapper '__hash__' of a object at 0x000001CB891BC7F0>), ('__init__', <bound method a.__init__ of <__main__.a object at 0x000001CB891BC7F0>>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x000001CB87CA6A70>), ('__le__', <method-wrapper '__le__' of a object at 0x000001CB891BC7F0>), ('__lt__', <method-wrapper '__lt__' of a object at 0x000001CB891BC7F0>), ('__module__', '__main__'), ('__ne__', <method-wrapper '__ne__' of a object at 0x000001CB891BC7F0>), ('__new__', <built-in method __new__ of type object at 0x00007FFCA630AB50>), ('__reduce__', <built-in method __reduce__ of a object at 0x000001CB891BC7F0>), ('__reduce_ex__', <built-in method __reduce_ex__ of a object at 0x000001CB891BC7F0>), ('__repr__', <method-wrapper '__repr__' of a object at 0x000001CB891BC7F0>), ('__setattr__', <method-wrapper '__setattr__' of a object at 0x000001CB891BC7F0>), ('__sizeof__', <built-in method __sizeof__ of a object at 0x000001CB891BC7F0>), ('__str__', <method-wrapper '__str__' of a object at 0x000001CB891BC7F0>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x000001CB87CA6A70>), ('__weakref__', None), ('dyn_prop', 3), ('myclassmethod', <bound method a.myclassmethod of <class '__main__.a'>>), ('test', <bound method a.test of <__main__.a object at 0x000001CB891BC7F0>>), ('x', 1), ('y', 2)] 

To summarize:

  • vars() and __dict__ only return instance-local properties;
  • dir() returns everything, but only as a list of string member names; dynamic properties are not called;
  • inspect.getmembers() returns everything, as a list of tuples (name, value); it actually runs dynamic properties, and accepts an optional predicate argument that can filter out members by value.

So my common-sense approach is typically to use dir() on the command line, and getmembers() in programs, unless specific performance considerations apply.

Note that, to keep things cleaner, I did not include __slots__ - if present, it was explicitly put there to be queried, and should be used directly. I also did not cover metaclasses, which can get a bit hairy (most people will never use them anyway).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.