148

How do you get a list of all variables in a class thats iteratable? Kind of like locals(), but for a class

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

    def as_list(self)
       ret = []
       for field in XXX:
           if getattr(self, field):
               ret.append(field)
       return ",".join(ret)

this should return

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo
4

10 Answers 10

220
dir(obj)

gives you all attributes of the object. You need to filter out the members from methods etc yourself:

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

example = Example()
members = [attr for attr in dir(example) if not callable(getattr(example, attr)) and not attr.startswith("__")]
print members   

Will give you:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']
Sign up to request clarification or add additional context in comments.

11 Comments

why instantiate an object: dir(Example()) instead of just the class type dir(Example)
and how do you get the values?
@knutole: getattr(object, attr)
How does callable(attr) work? Isn't attr a string?
you should have used vars(Example).items() or vars(instance.__class__).items() instead of dir() if you want to check if its callable or not because dir will only return 'strings as names..
|
169

If you want only the variables (without functions) use:

vars(your_object)

8 Comments

You still need to filter vars but this is the correct answer
really like this approach gonna use it to find out what to serialise before sending states over network for instance...
vars does not include the class variables, only the instance variables.
@DilithiumMatrix you need to use vars(THECLASSITSELF) on the class itself to get class variables. Check my answer below.
Using this method to specifically answer the OP's question: members = list(vars(example).keys()) as (at least in python3) vars returns a dict mapping the name of the member variable to it's value.
|
33

@truppo: your answer is almost correct, but callable will always return false since you're just passing in a string. You need something like the following:

[attr for attr in dir(obj()) if not callable(getattr(obj(),attr)) and not attr.startswith("__")]

which will filter out functions

Comments

7
>>> a = Example()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'bool143', 'bool2', 'blah',
'foo', 'foobar2000', 'as_list']

—as you see, that gives you all attributes, so you'll have to filter out a little bit. But basically, dir() is what you're looking for.

Comments

1

Similar to vars(), one can use the below code to list all class attributes. It is equivalent to vars(example).keys().

example.__dict__.keys()

Comments

1

Inspired by https://stackoverflow.com/a/13286863/14298786

class CONSTANT:
    a = 4
    b = 5

    def display() -> None:
        print("Hello!")


print(vars(CONSTANT))
# {'__module__': '__main__', 'a': 4, 'b': 5, 'display': <function CONSTANT.display at 0x1030bcb80>, '__dict__': <attribute '__dict__' of 'CONSTANT' objects>, '__weakref__': <attribute '__weakref__' of 'CONSTANT' objects>, '__doc__': None}
print(
    [k for k, v in vars(CONSTANT).items() if not callable(v) and not k.startswith("__")]
)
# ['a', 'b']
print(
    {
        k: v
        for k, v in vars(CONSTANT).items()
        if not callable(v) and not k.startswith("__")
    }
)
# {'a': 4, 'b': 5}

Comments

1
def get_class_variables(cls: type) -> set[str]:
    """Return set of class variables."""
    # Get class attributes
    attributes = vars(cls)

    # Filter out methods, nested classes and dunder (__) attributes
    return {
        key for key, value in attributes.items()
        if not callable(value) and not key.startswith("__")
    }

Example of how to use this function:

class Person:
    first_name: str = "Joseph"
    last_name: str = "ben-Yaakov"

# Then you can do this:
person_class_variables = get_class_variables(Person)

# or even this:
frodo = Person(first_name="Frodo", last_name="Baggins")
frodo_attributes = get_class_variables(frodo)

person_class_variables and frodo_attributes will both be the same:

{"first_name", "last_name"}

Comments

-2
row2dict = lambda r: {c.name: str(getattr(r, c.name)) for c in r.__table__.columns} if r else {}

Use this.

1 Comment

Misleading. There's no attribute 'table' in classes by default.
-3
ClassName.__dict__["__doc__"]

This will filter out functions, in-built variables etc. and give you just the fields that you need!

1 Comment

You sure it actually prints out empty!!!
-4

The easy way to do this is to save all instances of the class in a list.

a = Example()
b = Example()
all_examples = [ a, b ]

Objects don't spring into existence spontaneously. Some part of your program created them for a reason. The creation is done for a reason. Collecting them in a list can also be done for a reason.

If you use a factory, you can do this.

class ExampleFactory( object ):
    def __init__( self ):
        self.all_examples= []
    def __call__( self, *args, **kw ):
        e = Example( *args, **kw )
        self.all_examples.append( e )
        return e
    def all( self ):
        return all_examples

makeExample= ExampleFactory()
a = makeExample()
b = makeExample()
for i in makeExample.all():
    print i

3 Comments

I like the idea (I might actually use that in a current project). It's not an answer to the question, though: The OP wants to list the attributes, not the instances themselves.
@balpha: Ooops. Didn't read the question. 90% of the time, it's a duplicate of "how do I find all instances of a class." The actual question (now that you point it out) isn't sensible. You know the instance variables, just make a list.
ClassName.__dict__["__doc__"] This will filter out functions, in-built variables etc. and give you just the fields that you need!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.