[Tutor] __init__.py question

Alexandre Conrad alexandre.conrad at gmail.com
Wed Jun 1 20:52:44 CEST 2011


As a side note, remember that imported modules are cached under
sys.modules. If you import something, it will be looked up in
sys.modules and use the one in memory if it exists. If it doesn't
exist, it will iterate over sys.path and look for your module/package.
If it doesn't find it, you will get an ImportError. If it finds it, it
will add it to sys.modules. So any future imports for the same
namespace won't be re-imported from disk, it's already here in memory.

Say I *do* have a local package called string. After I import it, say
I want to import the "logging" module. Well, it will break:

$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import string  # my local string package
>>> print string
<module 'string' from 'string/__init__.pyc'>
>>> import logging
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/logging/__init__.py", line 62, in <module>
    elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
AttributeError: 'module' object has no attribute 'lower'

When "logging" is being imported, internally it also imports standard
Python "string" module, which is *already* in sys.modules (your own).

So imagine if Python also imported any directory without a __init__.py
file, system wide, you might have random surprises.


2011/6/1 Alexandre Conrad <alexandre.conrad at gmail.com>:
> 2011/5/31 Marilyn Davis <marilyn at pythontrainer.com>:
>> I don't really understand why __init__.py is necessary -- except that it
>> makes the packaging scheme work.
>>
>> The Python Manual by Guido van Rossum and Fred L. Drake says:
>>
>> ... this is done to prevent directories with a common name, such as
>> string, from unintentionally hiding valid modules that occur later on in
>> the module search path.
>
> I think it is just to avoids unexpected conflicting namespaces that
> could happen by accidentally importing non-Python directories. By
> explicitly putting a __init__.py module in your directory, you are
> telling Python you want your directory to be considered as a Python
> package and to be imported in your namespace. If you have a
> conflicting namespace, it means you explicitly wanted this to happen,
> then you have to deal with it (or fix it if unintended).
>
> --
> Alex | twitter.com/alexconrad
>



-- 
Alex | twitter.com/alexconrad


More information about the Tutor mailing list