redundant imports

Bengt Richter bokr at oz.net
Sat Apr 2 21:58:58 EST 2005


On Sat, 02 Apr 2005 16:44:29 -0600, Mike Meyer <mwm at mired.org> wrote:

>"max(01)*" <max2 at fisso.casa> writes:
>
>> Peter Hansen wrote:
>>> max(01)* wrote:
>>>
>>>> hi everybody.
>>>>
>>>> suppose that code-1.py imports code-2.py and code-3.py (because it
>>>> uses names from both), and that code-2.py imports code-3.py.
>>>>
>>>> if python were c, code-1.c should only *include* code-2.c, because
>>>> the latter in turns includes code-3.c.
>>>>
>>>> inclusion of modules in c is a purely preprocessing textual matter
>>>> (compilation is deferred to after the fact), i guess, so that such
>>>> things are possible. import of modules in python is a different
>>>> beast, so the "redundancy" is (i think) necessary.
>>>>
>>>> any comment/suggestion/idea?
>>> You're mixed up about this whole idea.
>>>
>>
>> that's why i am asking for advice here.
>> my concern was motivated by a (clumsy) attempt to understand the
>> difference of mechanism between the approach to modular programming in
>> a more "traditional" language (c) and python.
>
>[Names changed to be valid python module names.]
>
>I feel I ought to point out that you don't really *have* to import the
>code_3.py in code_1.py. You can get to things code_3.py in code_1.py
>as code_2.code_3.<thing>.
>
>The semantic behavior of "include" in C is the same as "from module
Bzzt ;-) It's not the same semantics!
>import *" in python. Both cases add all the names in the included
>namespace directly to the including namespace. This usage is
But a C #include results in processing as if the _source_ were substituted
into the including source in place of the #include line. That's not what
from module import * does, because when import executes the module's source
(happening only the first time BTW, unlike in-place #include)
it creates a module global that is distinct from the includer's global.
The import * creates local bindings to the objects visible as bindings
in the global space of the module, but the objects retain their module
global references (if any, since there doesn't have to be any).

IMO execfile('module.py') is closer to C's #include effect. Note:

 >>> print '----\n%s----'%open('impex.py').read()
 ----
 g = 'g in global space of impex.py'
 def showg(): print g

 ----
 >>> from impex import *
 >>> g
 'g in global space of impex.py'
 >>> showg()
 g in global space of impex.py
 >>> g = 'g in global space of importer'
 >>> g
 'g in global space of importer'
 >>> showg()
 g in global space of impex.py

Note that showg insisted on looking for g in it's idea of global.
Now we'll bring in g and showg via execfile:
 >>>
 >>> execfile('impex.py')
 >>> g
 'g in global space of impex.py'
 >>> showg()
 g in global space of impex.py
 >>> g = 'g in global space of importer'
 >>> showg()
 g in global space of importer

Note that because execfile executed the definition of showg in the
interactive global space, it sees the interactive change of g's binding
(in what it now also showg's global space).

(Execfile inside a function or class definition needs careful control, but can be done).

>depreciated in Python, because it leads to problems figuring out where
>a specific variable came from. In C, it creates a problem called "name
>space pollution". This is the case when a file1.c gets all the symbols
>for some_header.h, even though it doesn't include/need those symbols,
>because some header file1.c included needed a symbol from
>some_header.h. This is especially galling if the pollution collides
>with some_header2.h that file1.c actually needs.
>
Of course in C you could write some #ifxxx kludges to control inclusion of named things
from a given header file somewhat. But name space pollution is a pox, to be sure ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list