I have the following code in module xyz:
Class Outer:
Class Nested:
pass
I can successfully instantiate Outer
objects as follows
module = __import__("xyz", fromlist=[''])
the_class = getattr(module, "Outer")
instance = the_class()
However, when I replace "Outer"
with "Outer.Nested"
I get:
AttributeError: module 'xyz' has no attribute Outer.Nested
How can one make this work?
I should perhaps clarify that the above code is being used to instantiate classes whose type is unknown until runtime. Obviously I am not looking for instance = Outer.Nested()
.
Two ways to do this, suppose you have a string representing attribute access and a nested object:
>>> from types import SimpleNamespace
>>> module = SimpleNamespace(foo=SimpleNamespace(bar=SimpleNamespace(baz='tada!')))
>>> module
namespace(foo=namespace(bar=namespace(baz='tada!')))
The first is to basically parse the string yourself by splitting and using getattr
in a loop (or even, reduce
!):
>>> from functools import reduce
>>> reduce(getattr, "foo.bar.baz".split('.'), module)
'tada!'
Which is just equivalent to:
>>> result = module
>>> for attr in "foo.bar.baz".split("."):
... result = getattr(result, attr)
...
>>> result
'tada!'
Or use the built-in functools.attrgetter
factory function as a one-off:
>>> import operator
>>> operator.attrgetter("foo.bar.baz")(module)
'tada!'