Reputation: 31567
I've made a rather contrived import scheme in a project of mine and I think I might have discovered a bug in the Python interpreter that causes modules to be imported twice.
Here's how my test project is set up:
/
Launcher.bat — Project is run from here. It launches 'main/__init__.py` using the Python 3.2 executable
main/__init__.py — The __main__
script, the one launched by 'Launcher.bat'
main/foo.py — Contains an empty class
external/__init__.py — A script external to the 'main' project scripts, used to demonstrate the problem
./Launcher.bat
@echo off
C:\Python32\python.exe main\__init__.py
pause
./main/__init__.py
from foo import Foo
print("In 'main', Foo has id:", id(Foo))
# Add the directory from which 'Launcher.bat' was run,
# which is not the same as the './main' directory
# in which this script is located
import sys
sys.path.insert(1, '.')
# This script will try to import class Foo, but in doing so
# will casue the interpreter to import this './main/__init__.py'
# script a second time.
__import__('external')
./main/foo.py
class Foo:
pass
./external/__init__.py
from main.foo import Foo
print("In 'external', Foo has id:", id(Foo))
All of this will print the 'Main script was imported'
message twice. If the external script imports any other scripts, those too will be imported twice. I've only tested this on Python 3.2. Is this a bug, or did I make a mistake?
Output of the program is:
In 'main', Foo has id: 12955136
In 'main', Foo has id: 12955136
In 'external', Foo has id: 12957456
Press any key to continue . . .
Upvotes: 1
Views: 1119
Reputation: 287875
The first print
is misleading: Since you're not importing, but executing the file at the first time (__name__ == '__main__'
holds true), the main modules just gets imported once. Move the start point into a secondary file, or check for __name__ == '__main__'
.
By the way, circular import are a bad idea. You should resolve the circular import (by moving foo to a dedicated library). Alternatively, you can make your modules reentrant (i.e. check for the current directory being in sys.path
before adding it).
Upvotes: 1
Reputation: 72755
I don't think it's a bug. You should ask on the python-dev
list for a more authoritative answer. You are executing once (when you run the script) and importing once (from external) so the line gets printed twice. It's not importing twice.
However, this is a horrible setup. There are a lot of style violations here. Granted that some are for demonstration purposes only, it's still quite messy.
__init__.py
file as a file which should be run. The main entry point should be a script that imports the package. Upvotes: 2