Below is the hard way. Here is an easy way. I donβt know why this has not happened before.
import inspect def get_user_attributes(cls): boring = dir(type('dummy', (object,), {})) return [item for item in inspect.getmembers(cls) if item[0] not in boring]
Here begins
def get_user_attributes(cls): boring = dir(type('dummy', (object,), {})) attrs = {} bases = reversed(inspect.getmro(cls)) for base in bases: if hasattr(base, '__dict__'): attrs.update(base.__dict__) elif hasattr(base, '__slots__'): if hasattr(base, base.__slots__[0]): # We're dealing with a non-string sequence or one char string for item in base.__slots__: attrs[item] = getattr(base, item) else: # We're dealing with a single identifier as a string attrs[base.__slots__] = getattr(base, base.__slots__) for key in boring: del attrs['key'] # we can be sure it will be present so no need to guard this return attrs
It should be reliable enough. Essentially, it works if you ignore the attributes that are in the default subclass of object . Then it gets the mro of the class that went to it and traverses it in reverse so that the keys of the subclass can overwrite the keys of the superclass. It returns a dictionary of key-value pairs. If you need a list of keys, tuples of values, as in inspect.getmembers , then just return either attrs.items() or list(attrs.items()) in Python 3.
If you really don't want to navigate mro and just want the attributes defined directly in the subclass, then this is simpler:
def get_user_attributes(cls): boring = dir(type('dummy', (object,), {})) if hasattr(cls, '__dict__'): attrs = cls.__dict__.copy() elif hasattr(cls, '__slots__'): if hasattr(base, base.__slots__[0]): # We're dealing with a non-string sequence or one char string for item in base.__slots__: attrs[item] = getattr(base, item) else: # We're dealing with a single identifier as a string attrs[base.__slots__] = getattr(base, base.__slots__) for key in boring: del attrs['key'] # we can be sure it will be present so no need to guard this return attrs
aaronasterling Nov 22 '10 at 0:13 2010-11-22 00:13
source share