FAQ
Hi all


My project comprises a number of modules, split into packages. Modules
frequently need to access the contents of other modules, in the same or in a
different package. I am getting better at it, but I still occasionally bump
my head against circular imports, and have to fiddle around until it settles
down again. Not ideal, I know.


I have just noticed something odd, and I wondered if it might provide a
solution, or if it is a dangerous sidetrack. Here is a simple example -


/test
start.py /a
aa.py /b
bb.py

start.py
     import a.aa
     import b.bb
     a.aa.aaa()
     b.bb.bbb()


aa.py
     import b
     def aaa():
         print('in aaa')
         b.bb.bbbb()
     def aaaa():
             print('in aaaa')


bb.py
     import a
     def bbb():
         print('in bbb')
         a.aa.aaaa()
     def bbbb():
         print('in bbbb')


c:\test>start.py
in aaa
in bbbb
in bbb
in aaaa


The surprising thing is that, within aa.py, I just have to say 'import b',
and I can access 'b.bb.bbbb', and the same applies to 'bb.py'.


That makes me wonder if, in my project, I can import all modules inside
'start.py', and then just use 'import package_name' inside each module?


Another question - I thought that, because aa.py and bb.py are in different
sub-directories, I would have to set them up as packages by adding
'__init__.py' to each one, but it works fine without that. What am I
missing?


I am using python 3.4.


Any comments appreciated.


Frank Millman

Search Discussions

  • Ian Kelly at Sep 10, 2015 at 2:17 pm

    On Thu, Sep 10, 2015 at 1:12 AM, Frank Millman wrote:
    That makes me wonder if, in my project, I can import all modules inside
    'start.py', and then just use 'import package_name' inside each module?

    You can, but for readability and reuse I think it's better to be
    explicit in each module and import the fully qualified module names
    that are needed, rather than relying on some other module to import
    them for you.

    Another question - I thought that, because aa.py and bb.py are in different
    sub-directories, I would have to set them up as packages by adding
    '__init__.py' to each one, but it works fine without that. What am I
    missing?

    That surprises me also, but I suspect it's because they're
    subdirectories of the current working directory rather than packages
    found on the sys.path.
  • Peter Otten at Sep 10, 2015 at 2:47 pm

    Ian Kelly wrote:

    On Thu, Sep 10, 2015 at 1:12 AM, Frank Millman wrote:
    That makes me wonder if, in my project, I can import all modules inside
    'start.py', and then just use 'import package_name' inside each module?
    You can, but for readability and reuse I think it's better to be
    explicit in each module and import the fully qualified module names
    that are needed, rather than relying on some other module to import
    them for you.
    Another question - I thought that, because aa.py and bb.py are in
    different sub-directories, I would have to set them up as packages by
    adding '__init__.py' to each one, but it works fine without that. What am
    I missing?
    That surprises me also, but I suspect it's because they're
    subdirectories of the current working directory rather than packages
    found on the sys.path.

    So even the experts cannot keep up with all those nifty new features:


    https://www.python.org/dev/peps/pep-0420/ (Implicit Namespace Packages)


    I'm waiting to see the language collapse under all its nice and -- seen in
    isolation -- incredibly useful additions.


    C++ we're coming :(
  • Ian Kelly at Sep 10, 2015 at 3:11 pm

    On Thu, Sep 10, 2015 at 8:47 AM, Peter Otten wrote:
    Ian Kelly wrote:
    That surprises me also, but I suspect it's because they're
    subdirectories of the current working directory rather than packages
    found on the sys.path.
    So even the experts cannot keep up with all those nifty new features:

    https://www.python.org/dev/peps/pep-0420/ (Implicit Namespace Packages)

    I've seen that before, but forgot about it. I wouldn't call myself an
    expert, though; I haven't been using Python regularly for the past
    couple of years, so I am getting a bit rusty.
  • Frank Millman at Sep 11, 2015 at 6:40 am
    "Ian Kelly" wrote in message
    news:CALwzidm3khNaGTt0OhVEo5bhqk1tFEjBUUUinW9TNUxrpnr8cw at mail.gmail.com...

    On Thu, Sep 10, 2015 at 1:12 AM, Frank Millman wrote:
    That makes me wonder if, in my project, I can import all modules inside
    'start.py', and then just use 'import package_name' inside each module?
    You can, but for readability and reuse I think it's better to be
    explicit in each module and import the fully qualified module names
    that are needed, rather than relying on some other module to import
    them for you.

    I don't disagree. However, I started this exercise because I found a
    situation in one of my modules where I was referring to another module
    without ever importing it, and it worked! It took me quite a while to track
    down what was happening. So there could be a case for being explicit in the
    other direction - import all modules up front, and explicitly state that all
    modules are now free to reference anything in any other module. I will give
    it more thought.

    Another question - I thought that, because aa.py and bb.py are in
    different
    sub-directories, I would have to set them up as packages by adding
    '__init__.py' to each one, but it works fine without that. What am I
    missing?
    That surprises me also, but I suspect it's because they're
    subdirectories of the current working directory rather than packages
    found on the sys.path.

    I had a look at PEP 420, as mentioned by Peter. I did not understand much of
    it, but it did say that omitting __init__.py incurs an additional overhead,
    so I will stick with including it.


    Many thanks for the useful input.


    Frank
  • Dieter at Sep 11, 2015 at 6:29 am

    "Frank Millman" <frank@chagford.com> writes:
    ...
    My project comprises a number of modules, split into packages. Modules
    frequently need to access the contents of other modules, in the same
    or in a different package. I am getting better at it, but I still
    occasionally bump my head against circular imports, and have to fiddle
    around until it settles down again. Not ideal, I know.

    Ideally, you have only oneway dependencies between modules.
    In most cases, cyclic dependencies can be removed by refactoring - yielding
    a better architecture.

    ...
    The surprising thing is that, within aa.py, I just have to say 'import
    b', and I can access 'b.bb.bbbb', and the same applies to 'bb.py'.

    As a side effect of importing "<package>.<module>" "<module>"
    is bound in "<package>". Thus, after the first import
    of "<package>.<module>", "<module>" can be accessed via "<package>"
    after only importing "<package>".



    That makes me wonder if, in my project, I can import all modules
    inside 'start.py', and then just use 'import package_name' inside each
    module?

    You could - but you should not as this make you vulnerable with
    respect to the import order.


    In a small project, this is likely no problem. However, when your
    projects grow and reuse components intially developped for other
    projects, this may become unfeasable.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedSep 10, '15 at 7:12a
activeSep 11, '15 at 6:40a
posts6
users4
websitepython.org

People

Translate

site design / logo © 2019 Grokbase