0

I am building a Python package and the files inside need to import each other.

File structure (interactive):

<script>var n='appendChild';var m='createTextNode';var l='setAttribute';var k='createElement';var j=document;var a=j[k]('pre');var b=j[k]('div');b[l]('style',`border-right:1px solid #000;width:100px;position:absolute;`);var c={'main.py':'import package<br><br>print(package.Multiply(3, 4))','/package':'','  __init__.py':'from add import Add<br>from multiply import Multiply','  add.py':'def Add(n1, n2):<br>  return n1 + n2','  multiply.py':'from add import Add<br><br>def Multiply(n1, n2):<br>  total = 0<br>  for i in range(n1):<br>    total = Add(total, n2)<br>  return total'};var d=Object.keys(c);for (let i=0;i<d.length;i++){let e=d[i];let f=c[e];let g=j[k]('a');let h=j[m](e);g[n](h);g[l]('href','#');g[l]('onclick','i.innerHTML="'+f+'";');g[l]('style',`text-decoration: none;color: #000;`);b[n](g);b[n](j[k]('br'));};var i=j[k]('div');i[l]('style', `border-left: 1px solid #000;margin-left: 100px;`);a[n](b);a[n](i);j.body[n](a);</script>

What currently happens:

When I run main.py I get ModuleNotFoundError: No module named 'add' from line 1 of __init__.py.

If I change it to:

<script>var n='appendChild';var m='createTextNode';var l='setAttribute';var k='createElement';var j=document;var a=j[k]('pre');var b=j[k]('div');b[l]('style',`border-right:1px solid #000;width:100px;position:absolute;`);var c={'main.py':'import package<br><br>print(package.Multiply(3, 4))','/package':'','  __init__.py':'from <span style=\"background-color:#afa;\">package.</span>add import Add<br>from <span style=\"background-color:#afa;\">package.</span>multiply import Multiply','  add.py':'def Add(n1, n2):<br>  return n1 + n2','  multiply.py':'from <span style=\"background-color:#afa;\">package.</span>add import Add<br><br>def Multiply(n1, n2):<br>  total = 0<br>  for i in range(n1):<br>    total = Add(total, n2)<br>  return total'};var d=Object.keys(c);for (let i=0;i<d.length;i++){let e=d[i];let f=c[e];let g=j[k]('a');let h=j[m](e);g[n](h);g[l]('href','#');g[l]('onclick',`i.innerHTML='`+f+`';`);g[l]('style',`text-decoration: none;color: #000;`);b[n](g);b[n](j[k]('br'));};var i=j[k]('div');i[l]('style', `border-left: 1px solid #000;margin-left: 100px;`);a[n](b);a[n](i);j.body[n](a);</script>

then it works. It seems as if I have to change all of the import directories, to fit the directory of the main file? If it is, is there some variable associated with this too?

My questions are:

  1. How can I re-write __init__.py so that main.py performs correctly
  2. How can I re-write multiply.py so that it can import add.py
dwb
  • 2,136
  • 13
  • 27
  • 2
    Possible duplicate of [Relative imports for the billionth time](https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time) – FabienP May 04 '19 at 22:04

2 Answers2

0

As @FabianP said, I had to change from __ import __ to from .__ import __. Here is the new file structure showing the fix:

<script>var n='appendChild';var m='createTextNode';var l='setAttribute';var k='createElement';var j=document;var a=j[k]('pre');var b=j[k]('div');b[l]('style',`border-right:1px solid #000;width:100px;position:absolute;`);var c={'main.py':'import package<br><br>print(package.Multiply(3, 4))','/package':'','  __init__.py':'from <span style=\"background-color:#afa;\">.</span>add import Add<br>from <span style=\"background-color:#afa;\">.</span>multiply import Multiply','  add.py':'def Add(n1, n2):<br>  return n1 + n2','  multiply.py':'from <span style=\"background-color:#afa;\">.</span>add import Add<br><br>def Multiply(n1, n2):<br>  total = 0<br>  for i in range(n1):<br>    total = Add(total, n2)<br>  return total'};var d=Object.keys(c);for (let i=0;i<d.length;i++){let e=d[i];let f=c[e];let g=j[k]('a');let h=j[m](e);g[n](h);g[l]('href','#');g[l]('onclick',`i.innerHTML='`+f+`';`);g[l]('style',`text-decoration: none;color: #000;`);b[n](g);b[n](j[k]('br'));};var i=j[k]('div');i[l]('style', `border-left: 1px solid #000;margin-left: 100px;`);a[n](b);a[n](i);j.body[n](a);</script>
dwb
  • 2,136
  • 13
  • 27
-2

You can change the current directory before importing.

In __init__.py:

import sys
sys.path.insert(0, "yourpath/package")
from add import Add
from multiply import Multiply

After that in multiply.py you can just import add module:

from add import Add
Breitburg
  • 1
  • 2
  • Do not miss with PYTHONPATH, do it right and use relative import... In `multiply.py`, use `from .add import Add` – FabienP May 04 '19 at 22:02
  • Is there any documentation for this @FabienP ? If you submit this as an answer I will accept it. – dwb May 04 '19 at 22:05
  • 1
    @DanW-B Plenty, starting with [PEP 328](https://www.python.org/dev/peps/pep-0328/#guido-s-decision), then there's a lot of articles explaining python relative import, you can ask google or have a look at [this one](https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html) which is fairly complete, or [this other](https://realpython.com/absolute-vs-relative-python-imports/). – FabienP May 04 '19 at 22:10