Python packages and imports - clarification needed
Question: The import function of Python still confuses me sometimes. Here's an example:

My project has the following package structure:

    
    
    Project/
        src/
            example/
                __init__.py
                an_example.py
            top/
                __init__.py
                lin/
                    __init__.py
                    factory.py
    

In `an_example.py`, I'd like to write

    
    
    from top import lin
    if __name__ == '__main__':
        a = lin.factory.AClass()
    

However, this fails with:

    
    
        a = lin.factory.AClass()
    AttributeError: 'module' object has no attribute 'factory'
    

`an_example.py` works when written like this:

    
    
    from top.lin import factory
    if __name__ == '__main__':
        a = factory.AClass()
    

Can you explain to me why it is wrong to write the import statement like the
first version? I'd prefer a fully qualified name like `lin.factory.AClass` to
`factory.AClass`.


Answer: This is because, unless you tell `lin` to import `factory` in `__init__.py`,
then `factory` is not in the `lin` namespace.

E.g:

Presume your existing project structure, with an_example.py containing:

    
    
    from top import lin
    
    lin.factory.AClass()
    

With `top/lin/__init__.py` blank, we get `ImportError: No module named
factory`.

With `top/lin/__init__.py` containing `import top.lin.factory`, we get no
error.

When you ask to use `factory.AClass()`, it works because it is defined there.
Likewise, you need to define factory in `lin` if you want to use it from
there.

