Module cross reference design issue
<p>I have a python file called <code>testlib.py</code>, its intention is defined some utility class and global function used by other modules. The <code>uselib.py</code> is designed as a client which is using class/global functions from <code>testlib.py</code>.</p>

<p>Dues to some design issues, <code>testlib.py</code> needs to refer to some class <code>Goo</code> defined in <code>uselib.py</code>. If I just import directly, there will be error message (post below). </p>

<p>Just wondering how to handle this situation for cross reference elegantly in Python 2.7 </p>

<p><strong>uselib.py</strong>,</p>

<pre><code>import testlib

class Goo:
    def __init__(self):
        pass
    def checkValue(self):
        return "check value in Goo"

print testlib.globalFoo()
f = testlib.Foo()
print f.getValue()
</code></pre>

<p><strong>testlib.py</strong>,</p>

<pre><code>import uselib

class Foo:
    def __init__(self):
        pass
    def getValue(self):
        g = uselib.Goo()
        g.checkValue()
        return 'get value in class Foo'

def globalFoo():
    return 'in global foo'
</code></pre>

<p><strong>Error Message</strong>,</p>

<pre><code>Traceback (most recent call last):
  File "/Users/foo/personal/uselib.py", line 1, in &lt;module&gt;
    import testlib
  File "/Users/foo/personal/testlib.py", line 1, in &lt;module&gt;
    import uselib
  File "/Users/foo/personal/uselib.py", line 9, in &lt;module&gt;
    print testlib.globalFoo()
AttributeError: 'module' object has no attribute 'globalFoo'
</code></pre>

<p>I came up with a sneaky hack: only <code>import testlib</code> when you are already calling the <code>__main__</code> function in <code>uselib.py</code>. Using the check <code>if __name__ == "__main__"</code> in <code>uselib.py</code> is important in this case. That way, you avoid the circular importing. The <code>testlib.py</code> has all the classes in <code>uselib.py</code>, but <code>uselib.py</code> only loads everything in <code>testlib.py</code> when it needs calling them.</p>

<p>Code for <strong>uselib.py</strong>:</p>

<pre><code>#import testlib

class Goo:
    def __init__(self):
        pass
    def checkValue(self):
        return "check value in Goo"

if __name__ == "__main__":
    import testlib
    print testlib.globalFoo()
    f = testlib.Foo()
    print f.getValue()
</code></pre>

<p>Code for <strong>testlib.py</strong>:</p>

<pre><code>import uselib

class Foo:
    def __init__(self):
        pass
    def getValue(self):
        g = uselib.Goo()
        g.checkValue()
        return 'get value in class Foo'

def globalFoo():
    return 'in global foo'
</code></pre>

<p>Output:</p>

<pre><code>Chip chip@ 04:00:00@ ~: python uselib.py
in global foo
get value in class Foo
</code></pre>

<p>Note that: <code>import testlib</code> could also be called in any arbitary function in <code>uselib.py</code>, and it doesnot need to be <code>__main__</code>. E.g.:</p>

<p>Code for another <strong>uselib.py</strong>:</p>

<pre><code>#import testlib

class Goo:
    def __init__(self):
        pass
    def checkValue(self):
        return "check value in Goo"
def moretest():
   import testlib
   print testlib.globalFoo()
   f = testlib.Foo()
   print f.getValue()

#if __name__ == "__main__":
    #import testlib
    #print testlib.globalFoo()
    #f = testlib.Foo()
    #print f.getValue()
</code></pre>

<p>Code for <strong>stackoverflow.py</strong>:</p>

<pre><code>import uselib
uselib.moretest()
</code></pre>

<p>Calling <strong>stackoverflow.py</strong>:</p>

<pre><code>Chip chip@ 04:30:06@ ~: python stackoverflow.py
in global foo
get value in class Foo
</code></pre>

python python-2.7