[Tutor] __init__.py question

Marilyn Davis marilyn at pythontrainer.com
Wed Jun 1 21:26:55 CEST 2011


Maybe I'm getting what you say, Alexandre and Ramit.

When you import logging, it imports string, but it won't if you have a
string of your own already imported.

So, when logging depends on string, it'll get mine and crash.

But __init__.py helps what in this scenario?

The only scenario it helps, that I can understand so far, is if I make a
string directory that isn't part of a package that I'm making, but is in
its directory structure, accidentally using a library name that I want.

I guess I don't feel very satisfied because I would be happy with the
crash so that I can fix up my naming/architecture mistake rather than
depend on, and struggle with, the __init__.py scheme.

I teach Python and this is always a hard part for people.  It might help
if I understand it better.

Marilyn Davis




On Wed, June 1, 2011 11:52 am, Alexandre Conrad wrote:

> 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