How to import classes defined in __init__.py

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

  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

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

Method 2

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.)

Method 3

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'>

Method 4

Add something like this to lib/__init__.py

from .helperclass import Helper

now you can import it directly:

from lib import Helper

Method 5

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.

Method 6

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 *

Method 7

Maybe this could work:

import __init__ as lib


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x