6

My package has the following structure:

myPackage
 -- __init__.py <-- empty
 -- signal.py
 -- plot.py

signal.py contains:

from plot import plot_signal

def build_filter():
   ...

def other_function():
   plot_signal()

plot.py contains:

from signal import build_filter

def plot_signal():
   ...

def other_function():
   build_filter()

I then have my script that makes use of this package that contains something like:

import myPackage as mp

mp.plot.plot_signal()

When I run this I get an attribute error: module 'myPackage' has no attribute 'plot'

I'm not sure why its referring to plot as an attribute when its a module in my package, or why its referring to myPackage as a module.

I then tried importing my package and calling the function a different way:

from myPackage import plot, signal

plot.plot_signal()

However, now I get an import error: cannot import name 'build_filter' and the traceback is referring to plot.py where its trying to import the build_filter() function from a sibling module.

I'm thinking this has something to do with the fact that the 2 modules are using functions from one another, and recursively importing the other module.

What's the correct way to organize this package so that sibling modules can import functions from each other?

matino
  • 17,199
  • 8
  • 49
  • 58
Simon
  • 9,762
  • 15
  • 62
  • 119
  • @matino: I changed the language tag to "python-3.x" because that's what the OP is apparently using (python 2 produces different error messages). Why did you put it back to just "python"? – martineau Apr 27 '17 at 11:33
  • @martineau - I think that the problem is related to all versions of python, regardless of the error message but feel free to restore python-3x if you want to. – matino Apr 27 '17 at 11:35
  • @matino: Have you tried your solution in both versions? – martineau Apr 27 '17 at 11:38
  • @martineau - Yes I did – matino Apr 27 '17 at 11:52
  • Does this answer your question? [How to import the class within the same directory or sub directory?](https://stackoverflow.com/questions/4142151/how-to-import-the-class-within-the-same-directory-or-sub-directory) – mkrieger1 Apr 28 '22 at 08:55

1 Answers1

4

To make mp.plot.plot_signal() work, you must import plot in the myPackage.__init__.py. Another thing is that in both plot.py and signal.py you should import the whole module to avoid circular imports:

signal.py:

import myPackage.plot

myPackage.plot.plot_signal()

plot.py

import myPackage.signal

myPackage.signal.build_filter()

You could also use the relative imports in all 3 files but it will work only in Python 3.x:

signal.py:

from . import plot

plot.plot_signal()

plot.py

from . import signal

signal.build_filter()
matino
  • 17,199
  • 8
  • 49
  • 58
  • perfect, that seems to work. Is there a way to use relative imports in these 3 files so I dont need to manually specify the package name? (thats something that might change at some point) – Simon Apr 27 '17 at 11:43