0

I have a simple project trying to illustrate how Python Path works. Illustrated below is my current project structure.main.py looks like this,

import pathlib
import sys

cwd = pathlib.Path(__file__).parent.resolve()
source_directory = cwd / 'depth_1' / 'depth_2' / 'depth_3'
sys.path.append(str(source_directory))

Each row_x_file.py simply contains one function,

def row_x_print():
    print("Inside row_x_file.py")

(With the x substituted for the correct number). Each __init__.py is simply from . import *

Now, because I have added the path to depth_3 to the sys.path I can successfully type import row_1 without an error. However I can never access the function that is exported from the __init__, i.e. I cannot run row_1_print() after import row_1, but import row_1 runs without failure. from row_1 import row_1_print does not seem to succeed either.

How do I make it so after successfully typing import row_1 I can run the function inside of row_1_file.py?

enter image description here

Joe
  • 153
  • 9
  • It's been some time since I've freshly organized a project, but from what I recall you do not require to add `import` in `__init__.py `, the file is actually loaded when you load the module ( here it's the `row_1` module ) so it seems somewhat redundant. – pholat Nov 28 '22 at 09:51
  • please fill in the question with all the example code - so that we might point you in the right direction. I feel you might also want to use the code without the module prefix. Please let me know how is my answer not answering your question too. – pholat Dec 01 '22 at 10:06
  • It does now, cheers. – Joe Dec 01 '22 at 10:29

1 Answers1

0

In that example, you do not need to append to the python path at all.

For recreated example with such files:

d1/d2/d3/row_1/
    __init__.py
    test.py
main.py

and code: main.py

#!python3

from d1.d2.d3.row_1 import test

if __name__ == "__main__":
    print("text")
    test.foo();
    test.bar();

__init__.py

X="module"

test.py

from . import X

def foo():
    print("yay it works")

def bar():
    print(f"value X: {X}")

You would get the output:

text
yay it works
value X: module

Now, having working example, to demonstrate how the path behaves, edit main.py to:

#!python3

import pathlib, sys

cwd = pathlib.Path(__file__).parent.resolve()
source_directory = cwd / 'd1' / 'd2' / 'd3'
sys.path.append(str(source_directory))

from row_1 import test

if __name__ == "__main__":
    print("text")
    test.foo();
    test.bar();

Which example still works, though has the path changed therefore now the d1.d2.d3 prefix for library sourcing is not required. Please be cautious to not override libraries' names as it might be hard to pinpoint the issues why seemingly fine code doesn't work.

Questions: What is __init__.py for? and python module` documentation might be useful for further research.

pholat
  • 467
  • 5
  • 20
  • My original intent of this example was to demonstrate how Python Path is used to reduce `from` chaining into nested directories. – Joe Nov 28 '22 at 10:09
  • @Joe please let me know if the explanation fully answers your question now. – pholat Nov 28 '22 at 10:22