title: Is there a way to access __dict__ (or something like it) that includes base classes?
body: <p>Suppose we have the following class hierarchy:</p>
  
  <pre><code>class ClassA:
  
      @property
      def foo(self): return "hello"
  
  class ClassB(ClassA):
  
      @property
      def bar(self): return "world"
  </code></pre>
  
  <p>If I explore <strong>__<em>dict</em>__</strong> on ClassB like so, I only see the bar attribute:</p>
  
  <pre><code>for name,_ in ClassB.__dict__.items():
  
      if name.startswith("__"):
          continue
  
      print(name)
  </code></pre>
  
  <p>Output is bar</p>
  
  <p>I can roll my own means to get attributes on not only the specified type but its ancestors.  However, my question is whether there's already a way in python for me to do this without re-inventing a wheel.</p>
  
  <pre><code>def return_attributes_including_inherited(type):
      results = []
      return_attributes_including_inherited_helper(type,results)
      return results
  
  def return_attributes_including_inherited_helper(type,attributes):
  
      for name,attribute_as_object in type.__dict__.items():
  
          if name.startswith("__"):
              continue
  
          attributes.append(name)
  
      for base_type in type.__bases__:
          return_attributes_including_inherited_helper(base_type,attributes)
  </code></pre>
  
  <p>Running my code as follows...</p>
  
  <pre><code>for attribute_name in return_attributes_including_inherited(ClassB):
      print(attribute_name)
  </code></pre>
  
  <p>... gives back both bar and foo.</p>
  
  <p>Note that I'm simplifying some things: name collisions, using items() when for this example I could use dict, skipping over anything that starts with __, ignoring the possibility that two ancestors themselves have a common ancestor, etc.</p>
  
  <p>EDIT1 - I tried to keep the example simple.  But I really want both the attribute name and the attribute reference for each class and ancestor class.  One of the answers below has me on a better track, I'll post some better code when I get it to work.</p>
  
  <p>EDIT2 - This does what I want and is very succinct.  It's based on Eli's answer below.</p>
  
  <pre><code>def get_attributes(type):
  
      attributes = set(type.__dict__.items())
  
      for type in type.__mro__:
          attributes.update(type.__dict__.items())
  
      return attributes
  </code></pre>
  
  <p>It gives back both the attribute names and their references.</p>
  
  <p>EDIT3 - One of the answers below suggested using inspect.getmembers.  This appears very useful because it's like dict only it operates on ancestor classes as well.</p>
  
  <p>Since a large part of what I was trying to do was find attributes marked with a particular descriptor, and include ancestors classes, here is some code that would help do that in case it helps anyone:</p>
  
  <pre><code>class MyCustomDescriptor:
  
      # This is greatly oversimplified
  
      def __init__(self,foo,bar):
          self._foo = foo
          self._bar = bar
          pass
  
      def __call__(self,decorated_function):
          return self
  
      def __get__(self,instance,type):
  
          if not instance:
              return self
  
          return 10
  
  class ClassA:
  
      @property
      def foo(self): return "hello"
  
      @MyCustomDescriptor(foo="a",bar="b")
      def bar(self): pass
  
      @MyCustomDescriptor(foo="c",bar="d")
      def baz(self): pass
  
  class ClassB(ClassA):
  
      @property
      def something_we_dont_care_about(self): return "world"
  
      @MyCustomDescriptor(foo="e",bar="f")
      def blah(self): pass
  
  # This will get attributes on the specified type (class) that are of matching_attribute_type.  It just returns the attributes themselves, not their names.
  def get_attributes_of_matching_type(type,matching_attribute_type):
  
      return_value = []
  
      for member in inspect.getmembers(type):
  
          member_name = member[0]
          member_instance = member[1]
  
          if isinstance(member_instance,matching_attribute_type):
              return_value.append(member_instance)
  
      return return_value
  
  # This will return a dictionary of name &amp; instance of attributes on type that are of matching_attribute_type (useful when you're looking for attributes marked with a particular descriptor)
  def get_attribute_name_and_instance_of_matching_type(type,matching_attribute_type):
  
      return_value = {}
  
      for member in inspect.getmembers(ClassB):
  
          member_name = member[0]
          member_instance = member[1]
  
          if isinstance(member_instance,matching_attribute_type):
              return_value[member_name] = member_instance
  
      return return_value
  </code></pre>