Singleton

Hrvoje Niksic hniksic at xemacs.org
Wed Oct 10 10:29:47 EDT 2007


pythoncurious at gmail.com writes:

> Now when I run the 'run.py', it will print two different numbers.
> sys.modules tells me that 'mod1' is imported as both 'one.mod1' and
> 'mod1', which explains the result.

If I were you, I'd make sure that the module duplicate problem is
resolved first, for example by putting run.py somewhere outside one/.
Then the singleton problem disappears as well.

> It is possible to solve this by always importing with the complete
> path like 'one.mod1', even when inside the 'one' directory, but
> that's an error waiting to happen.

Is it, really?  As far as I can tell, Python handles that case rather
robustly.  For example:

$ mkdir one
$ touch one/__init__.py
$ touch one/mod1.py one/mod2.py
$ echo 'import mod2' > one/mod1.py
$ python
Python 2.5.1 (r251:54863, May  2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import one.mod1
>>> import sys
>>> sorted(sys.modules)
['UserDict', '__builtin__', '__main__', '_codecs', '_sre', '_types', 'codecs', 'copy_reg', 'encodings', 'encodings.aliases', 'encodings.codecs', 'encodings.encodings', 'encodings.types', 'encodings.utf_8', 'exceptions', 'linecache', 'one', 'one.mod1', 'one.mod2', 'os', 'os.path', 'posix', 'posixpath', 're', 'readline', 'rlcompleter', 'signal', 'site', 'sre_compile', 'sre_constants', 'sre_parse', 'stat', 'sys', 'types', 'warnings', 'zipimport']

Although mod1 imports mod2 simply with "import mod2", the fact that
mod1 itself is imported as part of "one" is respected.  As a result,
mod2 is imported as "one.mod2", exactly as if it were imported from
outside the "one" package.

run.py is an exception because it is started directly using "python
run.py", so it never gets the information that it's supposed to be
part of a package.  To fix the problem, all you need to do is make
sure that executable scripts such as run.py are either placed safely
outside the package, or that they take care to always use absolute
imports, such as "import one.mod1" instead of "import mod1".  Placing
them outside the package is a good example of preventing an error
waiting to happen, like the one you hinted at.



More information about the Python-list mailing list