[Tutor] __init__.py question

Steven D'Aprano steve at pearwood.info
Thu Jun 2 02:11:00 CEST 2011


Marilyn Davis wrote:
[...]
> There's something I'm missing because I think you simply can't call
> something string.py unless you are willing to give up the library
> string.py.

No, you're right about that. Python's search path is "first match wins". 
Whether it's a package or a module, it will match before the library 
string.py. Adding __init__.py doesn't change that.

(Unless you re-arrange sys.path so that library modules come first.)

However, you can have a directory called "string", containing arbitrary 
.py files. So you could drop this in your path:


string/
+-- a.py
+-- b.py

and add string to the path so that the directory is searched, and still 
get the standard string.py. (I haven't actually tried this, but it 
should work.)

Only if you put a file __init__.py into the directory will it shadow the 
standard library string.py.

Personally, I think the emphasis given in the docs about shadowing 
standard library files is misplaced. I think that is actually 
irrelevant. I think a more useful explanation for the need for 
__init__.py is simple: how else could Python distinguish a package from 
a mere directory containing Python files?

A mere directory is not searched unless it is explicitly added to the 
path; a mere directory cannot be imported. A package can be. But since a 
package *is* a directory at the file system level, how should Python 
distinguish them?

I suppose Python could have the rule "the directory must end in .py to 
be considered a package". But then, when you import the main package 
instead of a submodule, which file should Python read? There needs to be 
a standard naming convention for the file to be treated as the top-level 
module. But since you have such a file, there's no longer any need for 
adding a .py to the end of the directory name, since the standard file 
is sufficient to determine that the directory is a package.

That file could have been called anything, __init__.py was chosen by 
analogy with __init__ methods in classes and because it's unlikely to 
clash with any name package authors might choose for their own use.



-- 
Steven


More information about the Tutor mailing list