It's not quite that simple. If, instead of putting a simple print in you app's __init__.py file, you put:
import traceback
traceback.print_stack()
you will then be able to see what code is triggering the import of __init__.py. In the case where USE_I18N is True, you will see two identical tracebacks that look like this:
File "manage.py", line 12, in <module>
execute_manager(settings)
File "/usr/lib/python2.5/site-packages/django/core/management/__init__.py", line 362, in execute_manager
utility.execute()
File "/usr/lib/python2.5/site-packages/django/core/management/__init__.py", line 303, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python2.5/site-packages/django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/lib/python2.5/site-packages/django/core/management/base.py", line 213, in execute
translation.activate('en-us')
File "/usr/lib/python2.5/site-packages/django/utils/translation/__init__.py", line 73, in activate
return real_activate(language)
File "/usr/lib/python2.5/site-packages/django/utils/translation/__init__.py", line 43, in delayed_loader
return g['real_%s' % caller](*args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/utils/translation/trans_real.py", line 205, in activate
_active[currentThread()] = translation(language)
File "/usr/lib/python2.5/site-packages/django/utils/translation/trans_real.py", line 194, in translation
default_translation = _fetch(settings.LANGUAGE_CODE)
File "/usr/lib/python2.5/site-packages/django/utils/translation/trans_real.py", line 180, in _fetch
app = import_module(appname)
File "/usr/lib/python2.5/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/kmt/software/web/playground/ttt/__init__.py", line 2, in <module>
traceback.print_stack()
followed by:
Validating models...
0 errors found
Django version 1.1, using settings 'playground.settings'
Development server is running at
http://127.0.0.1:9999/Quit the server with CONTROL-C.
So indeed from the stack you can see that activating a translation (translation.activate('en-us')) is what ultimately causes the import of the app. This only happens if USE_I18N is True because when it is False the translation routines are replaced with do-nothing functions that don't actually do anything. So, when USE_I18N is False the translation.activate call you see in the stack trace wouldn't actually trigger your app to get loaded.
OK, so activating a translation causes your app to be loaded. Why does it happen twice when starting the dev server? The reason for that is the autoreload feature of the development server. If you run the dev server with USE_I18N set to True but the --noreload flag, you will see that __init__.py is imported only once before you get the message "Validating models...". Essentially entering the reloader loop causes a reload, so everything that has been run up to that point gets run again, including the translation activation that triggers the import of your app, if USE_I18N is True.
OK, so why don't you see the double load when USE_I18N is False and the reloader is active? If you look at the dev server output including stack trace from __init__.py for that case:
Validating models...
File "/usr/lib/python2.5/site-packages/django/core/management/commands/runserver.py", line 48, in inner_run
self.validate(display_num_errors=True)
File "/usr/lib/python2.5/site-packages/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/usr/lib/python2.5/site-packages/django/core/management/validation.py", line 28, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/usr/lib/python2.5/site-packages/django/db/models/loading.py", line 131, in get_app_errors
self._populate()
File "/usr/lib/python2.5/site-packages/django/db/models/loading.py", line 58, in _populate
self.load_app(app_name, True)
File "/usr/lib/python2.5/site-packages/django/db/models/loading.py", line 74, in load_app
models = import_module('.models', app_name)
File "/usr/lib/python2.5/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/kmt/software/web/playground/ttt/__init__.py", line 2, in <module>
traceback.print_stack()
0 errors found
Django version 1.1, using settings 'playground.settings'
Development server is running at
http://127.0.0.1:9999/Quit the server with CONTROL-C.
In this case your app isn't loaded until after the "Validating models..." message is printed. This is code that runs after the reloader reloads the first time. Disabling USE_I18N essentially moves the loading of your app from before entry to the reloader loop into the code that runs after the reloader enters the main processing loop. In this case you will see that your app gets loaded again when you do something that forces the reloader to reload again (i.e. change a code file).
Clear as mud?
Karen