0

Python iterating through object attributes

I found this question when trying to understand iteration over Objects, and found this response from Eric Leschinski:

class C:
    a = 5
    b = [1,2,3]
    def foobar():
        b = "hi"   

c = C

for attr, value in c.__dict__.iteritems():
    print "Attribute: " + str(attr or "")
    print "Value: " + str(value or "")

Which produced text that listed all attributes in class C, including functions and hidden attributes (surrounded by underscores) as seen below:

python test.py
Attribute: a
Value: 5
Attribute: foobar
Value: <function foobar at 0x7fe74f8bfc08>
Attribute: __module__
Value: __main__
Attribute: b
Value: [1, 2, 3]
Attribute: __doc__
Value:

Now, I understand how to filter out the 'hidden' attributes from my iteration, but is there a way to filter out all functions as well? Effectively, I'm looking for, in class C, only attributes a and b, listed sequentially, without the __module__ and __doc__ information and without any and all functions that happen to be in C.

Community
  • 1
  • 1
Humus
  • 95
  • 1
  • 7
  • https://docs.python.org/2/library/functions.html#callable – Jasper Feb 02 '15 at 20:24
  • if callable(attribute) – dylrei Feb 02 '15 at 20:28
  • possible duplicate of [Getting attributes of a class](http://stackoverflow.com/questions/9058305/getting-attributes-of-a-class) – Mazdak Feb 02 '15 at 20:29
  • @Kasra AD The difference in this case is that I'm looking for the values of the attributes, rather than the names of the attributes, though that might not have been conveyed clearly. – Humus Feb 02 '15 at 20:48

1 Answers1

2

You'll have to filter on type; function objects are attributes just like the rest. You could use the inspect.isfunction() predicate function here:

import inspect

for name, value in vars(C).iteritems():
   if inspect.isfunction(value):
       continue
   if name[:2] + name[-2:] == '____':
       continue

You could use the inspect.getmembers() function with a custom predicate:

isnotfunction = lambda o: not inspect.isfunction(o)
for name, value in inspect.getmembers(C, isnotfunction):
   if name[:2] + name[-2:] == '____':
       continue
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for the response! I'm not familiar with custom predicates, but couldn't the custom predicate also be used to filter out the hidden attributes as well? Something along the lines of `isnotfunctionorhidden = lambda o: not inspect.isfunction(o) and o.name[:2] + o.name[-2:] != '____'` – Humus Feb 02 '15 at 20:55
  • @Humus: the name is not passed to the predicate function, only the value. – Martijn Pieters Feb 02 '15 at 20:58
  • Ok, so the `o` passed into the lambda function isn't a pointer to the element being inspected? – Humus Feb 02 '15 at 21:03
  • @Humus: it is, but that doesn't give you the attribute name on the class. The `__doc__` attribute has the value `''` (empty string), so `''` is passed to the predicate. You cannot go from there to `'__doc__'`. – Martijn Pieters Feb 02 '15 at 21:06
  • Ok, thanks again. I didn't understand that the value, not the attribute, was being passed into the predicate. – Humus Feb 02 '15 at 21:09