Mailing List Archive

Problem with modules refering to each other
I have two python modules, both of which need to refer to classes
defined in the other one. How do I do this?

I am currently putting at the start of each module a line of the form:

from theOtherModule import *

However, this is not working. My modules -- greatly simplified -- look
like this:

#bak.py
from hhh import *
ti = AnHhhClass()
print ti

and:

#hhh.py
from bak import *
class AnHhhClass: pass

When I run ``python bak.py'', I get the error message
``NameError: AnHhhClass''.

--
Phil Hunt....philh@vision25.demon.co.uk
Problem with modules refering to each other [ In reply to ]
Phil Hunt wrote:

> #bak.py
> from hhh import *
>
> [...]
>
> #hhh.py
> from bak import *

Do we have a circular reference here?


//Klaus

--
···[ Magnetic Ink ]················································· ><> ···
···[ http://www.magnetic-ink.dk/ ]··········································
Problem with modules refering to each other [ In reply to ]
Phil Hunt <philh@vision25.demon.co.uk> wrote in message
news:934075710snz@vision25.demon.co.uk...
> I have two python modules, both of which need to refer to classes
> defined in the other one. How do I do this?
>
> I am currently putting at the start of each module a line of the form:
>
> from theOtherModule import *
>
> However, this is not working. My modules -- greatly simplified -- look
> like this:
>
> #bak.py
> from hhh import *
> ti = AnHhhClass()
> print ti
>
> and:
>
> #hhh.py
> from bak import *
> class AnHhhClass: pass
>
> When I run ``python bak.py'', I get the error message
> ``NameError: AnHhhClass''.
>
> --
> Phil Hunt....philh@vision25.demon.co.uk

Referring to something in an other module you have to put the modulename in
front:
Like in bak.py: "ti=hhh.AnHnnClass()"

/Peter
Problem with modules refering to each other [ In reply to ]
Phil Hunt wrote:

>>> #bak.py
>>> from hhh import *
>>>
>>> [...]
>>>
>>> #hhh.py
>>> from bak import *
>>
>> Do we have a circular reference here?
>
> Yes. Does Python not allow this? What's the workaround?

It seems python allows it, however, in this case it is not beneficial.
See, bak tells the interpreter to get all of hhh before proceeding but
as soon as python goes there it is told to go back and get the rest of
bak. At least thats how I perceive it.

I do not know the details of your code, so I cannot be sure, but a
workaround may have to include the creation of a third module and/or
repositioning the import statement(s) -- it's not a law that they have
to appear at the beginning, but sometimes it gives you a better over-
view.

I would try and reposition the the import statements first, then,
if this doesn't work, creating a third module and rearraniging things
so as to avoid circular references.

Let us know what you find out. :-)


//Klaus

--
···[ Magnetic Ink ]················································· ><> ···
···[ Delapsus resurgam ]····················································
Problem with modules refering to each other [ In reply to ]
Phil,

I agree with Klaus. About the imports. one thing to do might be to =
refer to the other module only from def or class statements.

Phil Hunt <philh@vision25.demon.co.uk> wrote in message =
news:934075710snz@vision25.demon.co.uk...
> I have two python modules, both of which need to refer to classes=20
> defined in the other one. How do I do this?=20
>=20
> I am currently putting at the start of each module a line of the form:
>=20
> from theOtherModule import *
>=20
> However, this is not working. My modules -- greatly simplified -- look
> like this:
>=20
> #bak.py
> from hhh import *
> ti =3D AnHhhClass()
> print ti

#bak.py
from hhh import *

def make_ti()
ti =3D AnHhhClass()
print "inside make_ti():", ti
return ti # If you need it outside of this function

# self test
if __name__ =3D=3D '__main__':
ti =3D make_ti()
print "outside at module:", ti
=20
> and:
>=20
> #hhh.py
> from bak import *
> class AnHhhClass: pass
>=20
> When I run ``python bak.py'', I get the error message=20
> ``NameError: AnHhhClass''.
>=20
> --=20
> Phil Hunt....philh@vision25.demon.co.uk
>=20

Karl Putland
kperacles@geocities.com
Problem with modules refering to each other [ In reply to ]
Phil Hunt writes:

> I have two python modules, both of which need to refer to classes
> defined in the other one. How do I do this?
>
> I am currently putting at the start of each module a line of the
> form:
>
> from theOtherModule import *
>
> However, this is not working. My modules -- greatly simplified --
> look like this:
>
> #bak.py
> from hhh import *
> ti = AnHhhClass()
> print ti
>
> and:
>
> #hhh.py
> from bak import *
> class AnHhhClass: pass
>
> When I run ``python bak.py'', I get the error message
> ``NameError: AnHhhClass''.

Plumbing rule #1: bak.py runs, Python hits the line with the "import"
statement, moves over to hhh.py. In hhh.py it hits the "import" line.
To protect itself against infinite recursion, it looks to see if
bak.py is being imported. In your case it's not, because what you
think of as "bak" is actually "__main__". So it starts importing bak
as a module. Hits the import line. Looks up hhh.py. This time it
detects recursion, so it just goes on, on the theory that whoever is
importing hhh.py will eventually complete the process. Which is true.

Plumbing rule #2: from module import ... doesn't do what you want. It
imports module, but not into your namespace. It takes what it finds
in the imported namespace and creates vars of the same name in your
namespace.

So when bak.py is imported, nothing has been bound into it's
namespace from hhh, because hhh's namespace is empty at that point.
Since the following line expects something from hhh to be bound into
bak.py's namespace, it fails.

So how do you fix this?

First, you never, ever use "from module import ..." unless (1)
the module has been specifically designed to allow this (see
what Tkinter or threading does to allow this) and (2) there are no
recursive imports going on.

Second, if you're doing recursive imports, you don't make any
references to items in the other module at the top level. They won't
be resolvable until the top level has been completely scanned.

Third, you remember that the script you run is not imported under
it's own name. It's in the import list, but as "__main__". Forgetting
this yields 2 copies of your module, and strange errors where vars
you set to new values don't change.

So bak.py should say:

import hhh

def doit()
it = hhh.AnHhhClass()
print it

And you should run a script that says:

import bak

bak.doit()

- Gordon
Problem with modules refering to each other [ In reply to ]
philh@vision25.demon.co.uk (Phil Hunt) writes:

> Yes. Does Python not allow this? What's the workaround? (Originally
> my two modules were one, with hhh containing subclasses of bak's
> classes, and bak containing code to dynamically create instances
> of hhh classes at run time, using:
>
> newInstance = eval(nameOfClass + '()')
>
> but I wanted the code split up into two modules as it is logically
> separate.)

A good way to implement this IMO, is to have a registry of classes in
bak.py like this:

# bak.py
class BaseClass:
# whatever
pass

registry = {}

def instantiate(classname, *args, **kw):
return apply(registry[classname], args, kw)


and in hhh.py:

# hhh.py
import bak

class SubClass(bak.BaseClass):
# whatever
pass

bak.registry['SubClass'] = SubClass


Code that has to create instances of SubClass would then call e.g.
bak.instantiate('SubClass')

This way, bak doesn't have to know anything about hhh or any other
module that implements sub-classes.



--
Bernhard Herzog | Sketch, a drawing program for Unix
herzog@online.de | http://www.online.de/home/sketch/
Problem with modules refering to each other [ In reply to ]
I think this is one of those things I had to forget about from
the world of 'C'. In Python you don't need to have an object
defined by some .H file to use it. Besides circular reverences
importing this way isn't much different than having one large
module.

As you know one large module isn't a nice thing.

Try something like passing a parm that allows access to
an object in another module. The parameter approach also
allows you to change the relationships of these modules
at runtime.

Decoupling from other modules is a good thing.

--
--Darrell

Phil Hunt <philh@vision25.demon.co.uk> wrote in message
news:934075710snz@vision25.demon.co.uk...
> I have two python modules, both of which need to refer to classes
> defined in the other one. How do I do this?
>
> I am currently putting at the start of each module a line of the form:
>
> from theOtherModule import *
>
> However, this is not working. My modules -- greatly simplified -- look
> like this:
>
> #bak.py
> from hhh import *
> ti = AnHhhClass()
> print ti
>
> and:
>
> #hhh.py
> from bak import *
> class AnHhhClass: pass
>
> When I run ``python bak.py'', I get the error message
> ``NameError: AnHhhClass''.
>
> --
> Phil Hunt....philh@vision25.demon.co.uk
>
Problem with modules refering to each other [ In reply to ]
[Phil Hunt, mutual imports]

Have you looked at the FAQ? 4.37, "How can I have modules that mutually
import each other?".

the-answer-is-"carefully"-ly y'rs - tim
Problem with modules refering to each other [ In reply to ]
In article <slrn7qq4as.cc2.kas@titan.magnetic-ink.dk>
kas@maps.magnetic-ink.dk "Klaus Alexander Seistrup" writes:
> Phil Hunt wrote:
> > #bak.py
> > from hhh import *
> >
> > [...]
> >
> > #hhh.py
> > from bak import *
>
> Do we have a circular reference here?

Yes. Does Python not allow this? What's the workaround? (Originally
my two modules were one, with hhh containing subclasses of bak's
classes, and bak containing code to dynamically create instances
of hhh classes at run time, using:

newInstance = eval(nameOfClass + '()')

but I wanted the code split up into two modules as it is logically
separate.)

--
Phil Hunt....philh@vision25.demon.co.uk
Problem with modules refering to each other [ In reply to ]
In article <7ojgv8$2drq@enews1.newsguy.com>
p.t@iname.com "Peter Torstenson" writes:
> Phil Hunt <philh@vision25.demon.co.uk> wrote in message
> news:934075710snz@vision25.demon.co.uk...
> > I have two python modules, both of which need to refer to classes
> > defined in the other one. How do I do this?
> >
> > I am currently putting at the start of each module a line of the form:
> >
> > from theOtherModule import *
> >
> > However, this is not working. My modules -- greatly simplified -- look
> > like this:
> >
> > #bak.py
> > from hhh import *
> > ti = AnHhhClass()
> > print ti
> >
> > and:
> >
> > #hhh.py
> > from bak import *
> > class AnHhhClass: pass
> >
> > When I run ``python bak.py'', I get the error message
> > ``NameError: AnHhhClass''.
>
> Referring to something in an other module you have to put the modulename in
> front:
> Like in bak.py: "ti=hhh.AnHnnClass()"

Unfortunately this doesn't work, I get ``NameError: hhh''.

--
Phil Hunt....philh@vision25.demon.co.uk
Problem with modules refering to each other [ In reply to ]
In article <000701bee1c2$25b868a0$722d2399@tim>
tim_one@email.msn.com "Tim Peters" writes:
> [Phil Hunt, mutual imports]
>
> Have you looked at the FAQ? 4.37, "How can I have modules that mutually
> import each other?".

Unfortunately the FAQ's been removed from the python distro that comes
with SuSE6.0.

I'll have a look at work tomorrow (where I have high-speed web access).

--
Phil Hunt....philh@vision25.demon.co.uk
Problem with modules refering to each other [ In reply to ]
In article <N8ir3.937$zN2.21156@typhoon.nyroc.rr.com>
news@dorb.com "Darrell" writes:
> Try something like passing a parm that allows access to
> an object in another module. The parameter approach also
> allows you to change the relationships of these modules
> at runtime.

I will probably do something like this -- I am thinking of re-writing
the software so that one module has a factory method in that creates
instances of that module's classes; the factory method is then passed
as a variable to the other module, which calls it when it want to
instanciate classes in the 1st module.


--
Phil Hunt....philh@vision25.demon.co.uk