Since the interest of this topic is to get fully qualified names, here is a pitfall that occurs when using relative imports along with the main module existing in the same package. E.g., with the below module setup:
$ cat /tmp/fqname/foo/__init__.py $ cat /tmp/fqname/foo/bar.py from baz import Baz print Baz.__module__ $ cat /tmp/fqname/foo/baz.py class Baz: pass $ cat /tmp/fqname/main.py import foo.bar from foo.baz import Baz print Baz.__module__ $ cat /tmp/fqname/foo/hum.py import bar import foo.bar
Here is the output showing the result of importing the same module differently:
$ export PYTHONPATH=/tmp/fqname $ python /tmp/fqname/main.py foo.baz foo.baz $ python /tmp/fqname/foo/bar.py baz $ python /tmp/fqname/foo/hum.py baz foo.baz
When hum imports bar using relative path, bar sees Baz.__module__ as just "baz", but in the second import that uses full name, bar sees the same as "foo.baz".
If you are persisting the fully-qualified names somewhere, it is better to avoid relative imports for those classes.
str(MyClass)[8:-2]