79516405

Date: 2025-03-18 05:56:27
Score: 1
Natty:
Report link

I posted a solution on the other question but someone pointed me to this. So let me give an answer to the "how" part of the OP's question "Why and how do you define a 'package'?"

The simple answer is you can edit __package__ and add the folder containing the root package to sys.path. But how do you do this cleanly and not totally clutter up the top of the Python script?

Using a known top-level package

Suppose your code some_script.py resides somewhere within a directory structure which looks like:

project_folder
|-- subdir
    |-- ab
        |-- cd
            |-- some_script.py
            |-- script1.py
        |-- script2.py
    |-- script3.py
|-- script4.py
|-- other_folder
    |-- script5.py

And you need your package to be subdir.ab.cd without knowing ab or cd or even the number of nested levels (as long as none of the intermediate levels are called "subdir" as well). Then you could use the following:

import os
import sys

if not __package__:
    __package__, __root__ = (
        (lambda p, d:
         (".".join(p[-(n := p[::-1].index(d) + 1):]), os.sep.join(p[:-n])))(
             os.path.realpath(__file__).split(os.sep)[:-1], "subdir"))
    sys.path.insert(0, __root__)

from .script1 import *
from ..script2 import *
from ...script3 import *
from subdir.script3 import *
from script4 import *
from other_folder.script5 import *

Using a known number of sub-levels

Suppose your code some_script.py resides somewhere within a directory structure which looks like:

project_folder
|-- ab
    |-- cd
        |-- some_script.py
        |-- script1.py
    |-- script2.py
|-- script3.py
|-- other_folder
    |-- script4.py

And you need your package to be ab.cd without knowing ab or cd but the depth of the package is guaranteed to be 2. Then you could use the following:

import os
import sys

if not __package__:
    __package__, __root__ = (  #
        (lambda p, n: (".".join(p[-n:]), os.sep.join(p[:-n])))(
            os.path.realpath(__file__).split(os.sep)[:-1], 2))
    sys.path.insert(0, __root__)

from .script1 import *
from ..script2 import *
from script3 import *
from other_folder.script4 import *

Relative imports and absolute imports all work

With the sys.path including the project folder, you also of course do any absolute imports from there. With __package__ correctly computed, one can now do relative imports as well. A relative import of .other_script will look for other_script.py in the same folder as some_script.py. It is important to have one additional level in the package hierarchy as compared to the highest ancestor reached by the relative path, because all the packages traversed by the ".."/"..."/etc will need to be a Python package with a proper name.

Reasons:
  • Blacklisted phrase (1): how do you
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • Low reputation (1):
Posted by: LastDuckStanding