How to import classes defined in __init__.py

PythonPackages

Python Problem Overview


I am trying to organize some modules for my own use. I have something like this:

lib/
  __init__.py
  settings.py
  foo/
    __init__.py
    someobject.py
  bar/
    __init__.py
    somethingelse.py

In lib/__init__.py, I want to define some classes to be used if I import lib. However, I can't seem to figure it out without separating the classes into files, and import them in __init__.py.

Rather than say:

    lib/
      __init__.py
      settings.py
      helperclass.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib.helperclass import Helper

I want something like this:

    lib/
      __init__.py  #Helper defined in this file
      settings.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib import Helper

Is it possible, or do I have to separate the class into another file?

EDIT

OK, if I import lib from another script, I can access the Helper class. How can I access the Helper class from settings.py?

The example here describes Intra-Package References. I quote "submodules often need to refer to each other". In my case, the lib.settings.py needs the Helper and lib.foo.someobject need access to Helper, so where should I define the Helper class?

Python Solutions


Solution 1 - Python

  1. 'lib/'s parent directory must be in sys.path.

  2. Your 'lib/__init__.py' might look like this:

     from . import settings # or just 'import settings' on old Python versions
     class Helper(object):
           pass
    

Then the following example should work:

from lib.settings import Values
from lib import Helper
Answer to the edited version of the question:

__init__.py defines how your package looks from outside. If you need to use Helper in settings.py then define Helper in a different file e.g., 'lib/helper.py'.

.
|   .
|   -- import_submodule.py     -- lib
|-- init.py
|-- foo
|   |-- init.py
|   -- someobject.py     |-- helper.py     -- settings.py




2 directories, 6 files
-- lib
|-- init.py
|-- foo
|   |-- init.py
|   .
|   .
|   -- import_submodule.py     -- lib
|-- init.py
|-- foo
|   |-- init.py
|   -- someobject.py     |-- helper.py     -- settings.py




2 directories, 6 files
-- lib
|-- init.py
|-- foo
|   |-- init.py
|   -- someobject.py     |-- helper.py     -- settings.py




2 directories, 6 files
-- settings.py

2 directories, 6 files

The command:

$ python import_submodule.py

Output:

settings
helper
Helper in lib.settings
someobject
Helper in lib.foo.someobject

# ./import_submodule.py
import fnmatch, os
from lib.settings import Values
from lib import Helper

print
for root, dirs, files in os.walk('.'):
    for f in fnmatch.filter(files, '*.py'):
        print "# %s/%s" % (os.path.basename(root), f)
        print open(os.path.join(root, f)).read()
        print


# lib/helper.py
print 'helper'
class Helper(object):
    def __init__(self, module_name):
        print "Helper in", module_name


# lib/settings.py
print "settings"
import helper

class Values(object):
    pass

helper.Helper(__name__)


# lib/__init__.py
#from __future__ import absolute_import
import settings, foo.someobject, helper

Helper = helper.Helper


# foo/someobject.py
print "someobject"
from .. import helper

helper.Helper(__name__)


# foo/__init__.py
import someobject

Solution 2 - Python

If lib/__init__.py defines the Helper class then in settings.py you can use:

from . import Helper

This works because . is the current directory, and acts as a synonym for the lib package from the point of view of the settings module. Note that it is not necessary to export Helper via __all__.

(Confirmed with python 2.7.10, running on Windows.)

Solution 3 - Python

You just put them in __init__.py.

So with test/classes.py being:

class A(object): pass
class B(object): pass

... and test/__init__.py being:

from classes import *

class Helper(object): pass

You can import test and have access to A, B and Helper

>>> import test
>>> test.A
<class 'test.classes.A'>
>>> test.B
<class 'test.classes.B'>
>>> test.Helper
<class 'test.Helper'>

Solution 4 - Python

Add something like this to lib/__init__.py

from .helperclass import Helper

now you can import it directly:

from lib import Helper

Solution 5 - Python

Edit, since i misunderstood the question:

Just put the Helper class in __init__.py. Thats perfectly pythonic. It just feels strange coming from languages like Java.

Solution 6 - Python

Yes, it is possible. You might also want to define __all__ in __init__.py files. It's a list of modules that will be imported when you do

from lib import *

Solution 7 - Python

Maybe this could work:

import __init__ as lib

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscottmView Question on Stackoverflow
Solution 1 - PythonjfsView Answer on Stackoverflow
Solution 2 - PythonyoyoView Answer on Stackoverflow
Solution 3 - PythonAaron MaenpaaView Answer on Stackoverflow
Solution 4 - PythonDawid GosławskiView Answer on Stackoverflow
Solution 5 - PythonRichard LevasseurView Answer on Stackoverflow
Solution 6 - PythonvartecView Answer on Stackoverflow
Solution 7 - PythonTurionView Answer on Stackoverflow