class A(): pass
a = A()
b = A()
a.b = b
b.c = 1
a.b # this is b
getattr(a, \"b\") # so is this
a.b.c # this is 1
getattr(a, \"b.c\") # this raises an Attrib
What should return getattr('a.b', {'a': None}, 'default-value'}? Should it raise AttributeError or just return 'default-value'? That's why complex keys if introduced in getattr would make it obscure to use.
So, it's more natural to view getattr(..) function as get method of dictionary of object attributes.