views:

102

answers:

3

For getting all the defined class attributes I try to go with

TheClass.__dict__

but that also gives me the special attributes. Is there a way to get only the self-defined attributes or do I have to "clean" the dict myself?

+2  A: 

You can't clean the __dict__:

AttributeError: attribute '__dict__' of 'type' objects is not writable

You could rely on naming conventions:

class A(object):
    def __init__(self, arg):
        self.arg = arg

    class_attribute = "01"    

print [ a for a in A.__dict__.keys() 
        if not (a.startswith('__') and a.endswith('__')) ]

# => ['class_attribute']

This may not be reliable, since you can of course overwrite or implement special/magic methods like __item__ or __len__ in your class.

The MYYN
+2  A: 

I don't think there's anything simple, and why would there be? There's no language-enforced difference between magic and user-defined attributes.

MYYN's solution won't work if you have a user-defined attribute starting with '__'. However, it does suggest a solution based on conventions: if you want to introspect your own classes, you can define your own naming convention, and filter on that.

Perhaps if you explain the need we can find a better solution.

Vladimir Gritsenko
+4  A: 

Another solution:

class _BaseA(object):
    _intern = object.__dict__.keys()

class A(_BaseA):
    myattribute = 1

print filter(lambda x: x not in A._intern+['__module__'], A.__dict__.keys())

I don't think this is terribly robust and there might still be a better way.

This does adress some of the basic issues some of the other answers pointed at:

  • No need for 'name convention' based-filtering
  • Providing your own implementation of magic methods, e.g. __len__ is no problem (define in A).
ChristopheD
Neat! Using subclasses this way did not occur to me.
Vladimir Gritsenko