No, dir() does not give that distinction.
You'd have to manually traverse the class MRO and produce the list yourself:
def dir_with_context(cls):
for c in cls.__mro__:
for name in sorted(c.__dict__):
yield (c, name)
This produces:
>>> list(dir_with_context(Child))
[(<class '__main__.Child'>, '__doc__'), (<class '__main__.Child'>, '__module__'), (<class '__main__.Child'>, 'child_method1'), (<class '__main__.Parent'>, '__dict__'), (<class '__main__.Parent'>, '__doc__'), (<class '__main__.Parent'>, '__module__'), (<class '__main__.Parent'>, '__weakref__'), (<class '__main__.Parent'>, 'parent_method1'), (<class '__main__.Parent'>, 'parent_method2'), (<type 'object'>, '__class__'), (<type 'object'>, '__delattr__'), (<type 'object'>, '__doc__'), (<type 'object'>, '__format__'), (<type 'object'>, '__getattribute__'), (<type 'object'>, '__hash__'), (<type 'object'>, '__init__'), (<type 'object'>, '__new__'), (<type 'object'>, '__reduce__'), (<type 'object'>, '__reduce_ex__'), (<type 'object'>, '__repr__'), (<type 'object'>, '__setattr__'), (<type 'object'>, '__sizeof__'), (<type 'object'>, '__str__'), (<type 'object'>, '__subclasshook__')]
The function can easily be augmented to skip names already seen in a subclass:
def dir_with_context(cls):
seen = set()
for c in cls.__mro__:
for name in sorted(c.__dict__):
if name not in seen:
yield (c, name)
seen.add(name)
at which point it produces the exact same number of entries as dir(Child), except for the order the names appear in (the above groups them per class):
>>> sorted(name for c, name in dir_with_context(Child)) == dir(Child)
True