23

I have a hello1 package that contains good.py module.

hello1
├── __init__.py
└── good.py

The init module has a variable A = 1, and I need to access the variable hello1.A in good.py.

import hello1

class Good(object):
    def __init__(self):
        print hello1.A

if __name__ == "__main__":
    g = Good()

The issue is that when I execute the python script I got ImportError: 'No module named hello1' error. I could add import sys; sys.path.append("..") at the first line of good.py for a quick fix.

However, the good.py is in hello1 package where the __init__.py is also in, so I wonder if there is a way to access the variables in __init__.py from the modules in the same package.

falsetru
  • 357,413
  • 63
  • 732
  • 636
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • 1
    Have you tried going to the directory containing `hello1` and running the script with `python hello1\good.py`? Also, you might find an answer here: http://stackoverflow.com/questions/436497/python-import-the-containing-package – flornquake Aug 16 '13 at 13:54

5 Answers5

11

From Python: import the containing package:

Importing __init__ seems to work fine.

import __init__

class Good(object):
    def __init__(self):
        print hello1.A
Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • 10
    You should not import `__init__` directly. Instead, the parent directory of `hello1` should be listed in the python module search path and `hello1` should be imported instead. – Martijn Pieters Dec 12 '14 at 14:42
  • 1
    If you use `python -m hello1.good` instead, then the current working directory is added to the path automatically; if that is the parent directory of `hello1` everything works just fine. – Martijn Pieters Dec 12 '14 at 14:48
  • @MartijnPieters, Not always. If you have an executable located inside the package, and say the executable wants to lookup the package's version number located in __init__.py, this is exactly what you should do. – Cerin Apr 29 '15 at 22:37
  • 2
    @Cerin: no, it is better to avoid putting executables in packages. In Python 3 you can now assign to the `__package__` variable to make relative imports work (see [PEP-366](https://www.python.org/dev/peps/pep-0366/)), after which you could use `from . import version`, but generally speaking you want to put your executables at the top level. – Martijn Pieters Apr 30 '15 at 15:08
  • @MartijnPieters, I couldn't disagree more. It's a common practice. Especially with tools which are implemented as *just* a package like `howdoi`. – Cerin May 01 '15 at 02:24
  • 2
    @Cerin: You misunderstood me, I think. `howdoi` follows best practices, yes, by having `setuptools` create a console script (the executable) *outside* the package. So `howdoi/howdoi` is not the script, it is a module servicing the actual script, so `from . import __version__` works there because `howdoi` is still a package. *Nowhere in that package is there a `import __init__` present nor needed*. – Martijn Pieters May 01 '15 at 07:08
1

If you don't like sys.path.append(...) you could run your script as

python -m hello1.good

in the directory containing the "hello1"-directory or use the PYTHONPATH environment variable instead of sys.path.

sebastian
  • 9,526
  • 26
  • 54
1

If I'm not mistaken you want to do something like:

python hello1/good.py

Since good.py is a submodule of a package you shouldn,'t run it directly; keep in mind that when directly executing it, then it isn't considered as part of the hello1 package, which prevents relative imports and the current directory is the one that contains the file, hence hello1 cannot be found if it isn't part of the PYTHONPATH. Instead you can run it using the -m switch of the python interpreter:

-m mod : run library module as a script (terminates option list)

I personally don't like using the interpreter options to execute a python file. I'd rather have an independent launcher file good.py that imports the hello1.good module and uses it to do what it has to do.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
1

You have to explicit import the constants you want to use.

It's preferable to have all your constants in a "config" file (i.e. config.py) ) and then if you want them in the package namespace, import them.

init.py file:

from package.config import *

it's more clear that way

6160
  • 1,002
  • 6
  • 15
-1
import __init__

...leads to: No module named 'init'

Massimo
  • 24
  • 5