How to list all fields of a class (and no methods)?

Question:

Suppose o is a Python object, and I want all of the fields of o, without any methods or __stuff__. How can this be done?

I’ve tried things like:

[f for f in dir(o) if not callable(f)]

[f for f in dir(o) if not inspect.ismethod(f)]

but these return the same as dir(o), presumably because dir gives a list of strings. Also, things like __class__ would be returned here, even if I get this to work.

Asked By: Eric Wilson

||

Answers:

This should work for callables:

[f for f in dir(o) if not callable(getattr(o,f))]

You could get rid of the rest with:

[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')]
Answered By: Benjamin Toueg

You can get it via the __dict__ attribute, or the built-in vars function, which is just a shortcut:

>>> class A(object):
...     foobar = 42
...     def __init__(self):
...         self.foo = 'baz'
...         self.bar = 3
...     def method(self, arg):
...         return True
...
>>> a = A()
>>> a.__dict__
{'foo': 'baz', 'bar': 3}
>>> vars(a)
{'foo': 'baz', 'bar': 3}

There’s only attributes of the object. Methods and class attributes aren’t present.

Answered By: Maxime Lorant

You could use the built-in method vars()

Answered By: El Bert

The basic answer is “you can’t do so reliably”. See this question.

You can get an approximation with [attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr))].

However, you shouldn’t rely on this, because:

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.

In other words, there is no canonical way to get a list of “all of an object’s attributes” (or “all of an object’s methods”).

If you’re doing some kind of dynamic programming that requires you to iterate over unknwon fields of an object, the only reliable way to do it is to implement your own way of keeping track of those fields. For instance, you could use an attribute naming convention, or a special “fields” object, or, most simply, a dictionary.

Answered By: BrenBarn

You can iterate through an instance’s __dict__ attribute and look for non-method things.
For example:

CALLABLES = types.FunctionType, types.MethodType
for key, value in A().__dict__.items():
    if not isinstance(value, CALLABLES):
        print(key)

Output:

foo
bar

You can do it in a single statement with a list comprehension:

print([key for key, value in A.__dict__.items() if not isinstance(value, CALLABLES)])

Which would print ['foo', 'bar'].

Answered By: martineau

You can get it via fields attribute: o._fields_

Answered By: ENEG
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.