0

For example, I have a project named myproject. In myproject directory. there are other sub-directory and main.py. And in other sub-directory, there are a.py and b.py.

The content in a.py is

import b

The content in main.py is:

from other.a import *

Here comes a problem, in main.py, when I use from other.a import *, the the content of a.py is included in main.py, it will raise an error, because b.py is in other, so in main.py using import b is wrong, and we should use import other.b, but a.py needs import b, so it is contradictory. How can I solve it?

Gauss
  • 379
  • 5
  • 18
  • 3
    Possible duplicate of [Python project structure and relative imports](https://stackoverflow.com/questions/34732916/python-project-structure-and-relative-imports) – Martin Alonso Aug 02 '17 at 09:31
  • 1
    @MartinAlonso The question you linked is very different from this one. – Sven Marnach Aug 02 '17 at 09:32
  • You should not use relative imports inside packages. In Python 3, they don't work, and in Python 2 they are deprecated. So in `a.py` you need to do `from . import b` or `import other.b`. – Sven Marnach Aug 02 '17 at 09:35
  • 2
    And don't mess with `sys.path`, as suggested in the other question. It's sometimes helpful for testing, and special circumstances, but in general you are better off leaving the management of `sys.path` to distribution utilities. – Sven Marnach Aug 02 '17 at 09:37
  • @SvenMarnach But `a.py` need `import b`, if I use `import other.b` in `a.py`, when I run `a.py`, it also will raise a error. – Gauss Aug 02 '17 at 10:26
  • 1
    @Gauss If `a.py` is part of a package, it can't be run dicrectly. That's intended. Modules in a package are supposed to provide functions and classes for use by other parts of the program, but they are not supposed to have side effects when imported. In some circumstances it's useful to make a module directly runnable, but you would need to run it using `python -m other.a`. However, this is an advanced approach for special situations. – Sven Marnach Aug 02 '17 at 12:15

1 Answers1

1

I think this is your code structure, correct?

mypackage
    other
        __init__.py
        a.py # import b
        b.py # def func_b()
    __init__.py
    main.py # from other.a import *

You can use this code structure:

DON'T USE ABSOLUTE IMPORT in your installable package such as: from mypackage.other import b in main.py, Use relative import such as: from .other import b in main.py.

mypackage
    other
        __init__.py
        a.py # from . import b
        b.py
    __init__.py
    main.py # from .other.a import *

then you can do this in main.py:

b.func_b(...)

Because by doing this, when you have a script test.py

from mypackage import main

main.b.func_b()

underlying it does from .other.a import *, because you have from . import b in a.py. so the * is actually b, that's why you can use b.func_b() in main.py.

MacSanhe
  • 2,212
  • 6
  • 24
  • 32