Beautiful Python

G

Gekitsuu

I've been reading a lot of python modules lately to see how they work
and I've stumbled across something that's sort of annoying and wanted
to find out of there was a good reason behind it. In a Perl program
when you're calling other modules you'll add "use" statements at the
beginning of your script like:

use strict;
use WWW::Mechanize;
use CGI;

This seems to be the de facto standard in the Perl community but in
python it seems most of the code I look at has import statements
everywhere in the code. Is there a sound reason for putting the imports
there are are developers just loading modules in as they need them. I
own Damian Conway's book of Perl Best Practices and it seems from a
maintainability standpoint that having all the modules declared at the
beginning would make it easier for someone coming behind you to see
what other modules they need to use yours. Being new I didn't know if
there was a performance reason for doing this or it is simply a common
habit of developers.
 
J

Jarek Zgoda

Gekitsuu napisal(a):
use strict;
use WWW::Mechanize;
use CGI;

This seems to be the de facto standard in the Perl community but in
python it seems most of the code I look at has import statements
everywhere in the code. Is there a sound reason for putting the imports
there are are developers just loading modules in as they need them. I
own Damian Conway's book of Perl Best Practices and it seems from a
maintainability standpoint that having all the modules declared at the
beginning would make it easier for someone coming behind you to see
what other modules they need to use yours. Being new I didn't know if
there was a performance reason for doing this or it is simply a common
habit of developers.

Sometimes putting import statements at the beginning is not feasible
(i.e. only when some condition has been met), as importing has some
impact on program execution (importing executes code in imported
module). This does not resemble Java imports (I don't know Perl).
 
S

Steven D'Aprano

Is there a sound reason for putting the imports
there are are developers just loading modules in as they need them. I
own Damian Conway's book of Perl Best Practices and it seems from a
maintainability standpoint that having all the modules declared at the
beginning would make it easier for someone coming behind you to see
what other modules they need to use yours.

Maintainability is a good reason for doing imports at the beginning of
your module. But it isn't the only consideration:

- if your module only imports modules which are part of the standard
library, the maintainability argument is irrelevant (except possibly for
very special cases like "I want to back-port your module to Python 1.5,
what modules do I need?").

- Encapsulation: sometimes you want to import objects so they are local to
a function or class. If you import them at the beginning of the module,
they will be global to the module.

- Cost: importing a module may not be cheap. Why pay that cost if you
don't need to? Sometimes it makes sense to delay importing until you
know you really need it.

- Namespace pollution: when a module imports your module, it will see
everything you have imported. By delaying imports to a local scope, you
reduce the number of objects in your module namespace that get exported.

These arguments are especially strong when using the "from module import
name" form of import.

Putting all your imports together at the beginning is recommended
but not compulsory precisely because there can be good reasons for
delaying imports. Think of "always do your imports at the beginning" as a
guideline, not a law. If you are writing something like:

import A
....code...
import B
....code...
import C
....code...

then this should be re-written as:

import A
import B
import C # or just import A, B, C
....code...

But if you are writing:

import A
....code...
def foo():
import B
# module B is only used in foo
...code...

then I don't think there is anything necessarily wrong with that.
 
C

Chip Turner

I've been reading a lot of python modules lately to see how they work
and I've stumbled across something that's sort of annoying and wanted
to find out of there was a good reason behind it. In a Perl program
when you're calling other modules you'll add "use" statements at the
beginning of your script like:

use strict;
use WWW::Mechanize;
use CGI;

This seems to be the de facto standard in the Perl community but in
python it seems most of the code I look at has import statements
everywhere in the code. Is there a sound reason for putting the imports
there are are developers just loading modules in as they need them. I
own Damian Conway's book of Perl Best Practices and it seems from a
maintainability standpoint that having all the modules declared at the
beginning would make it easier for someone coming behind you to see
what other modules they need to use yours. Being new I didn't know if
there was a performance reason for doing this or it is simply a common
habit of developers.

There is a crucial difference between Perl's 'use' and Python's
'import' -- when they are executed. Glossing over some details, in
Perl, a 'use' is evaulated when a .pl or .pm file is parsed, whereas in
Python import is executed when the statement is encountered in normal
program flow. One result of this is that, in Perl, this does not do
what you expect:

if ($some_condition) {
use SomeWierdModule;
}

What happens is that at parse time, SomeWierdModule is loaded, ignoring
completely the if statement. This, however, works fine in Python:

if some_condition:
import some_weird_module

In this case, some_weird_module will only be imported if some_condition
holds true when program flow hits the conditional.

The net result is that in Perl, putting use statements all over the
code has no real effect, because they all get evaluated at parse time
-- you may as well toss them prettily at the top. In Python, though,
there are occasional times where you *do* want to conditionally load a
module, so it occasionally makes sense to put them in other places.
Short of situations like the conditional importing above, though, I
would be highly suspicious of code that gratuitously tosses imports in
odd places; the namespace is global, after all; may as well be explicit
upfront.

You can really see this in action with the following:

perl <<EOF
if (0) {
use SomeWeirdModule;
}
EOF

vs

python <<EOF
if 0:
import some_weird_module;
EOF

The perl snippet explodes on an invalid module, whereas the python
behaves just fine.

HTH,
Chip
 
S

sconce

Gekitsuu said:
I've been reading a lot of python modules lately to see how they work
and I've stumbled across something that's sort of annoying and wanted
to find out of there was a good reason behind it. In a Perl program
when you're calling other modules you'll add "use" statements at the
beginning of your script like:

use strict;
use WWW::Mechanize;
use CGI;

This seems to be the de facto standard in the Perl community but in
python it seems most of the code I look at has import statements
everywhere in the code. Is there a sound reason for putting the imports
there are are developers just loading modules in as they need them. I
own Damian Conway's book of Perl Best Practices and it seems from a
maintainability standpoint that having all the modules declared at the
beginning would make it easier for someone coming behind you to see
what other modules they need to use yours. Being new I didn't know if
there was a performance reason for doing this or it is simply a common
habit of developers.


Without taking anything away from other posts responding to your
question, the first response perhaps should have been:

"Imports are always put at the top of the file, just after
any module comments and docstrings, and before module
globals and constants."

Which is the "official" Python style guide, PEP 0008, at
http://www.python.org/peps/pep-0008.html
and basically a reflection of Guido's own recommendations.

There are reasons to break almost any rule sometimes(*), but I think
you were asking whether there IS a rule -- which is an insightful,
worthy question if you've been looking at code which begs it.

-Bill


(*) PEP 0008 itself says, even before it lays out any rules,
"know when to be inconsistent".
 
R

rbt

Without taking anything away from other posts responding to your
question, the first response perhaps should have been:

"Imports are always put at the top of the file, just after
any module comments and docstrings, and before module
globals and constants."

Which is the "official" Python style guide, PEP 0008, at
http://www.python.org/peps/pep-0008.html
and basically a reflection of Guido's own recommendations.

I've always done it this way (import at the top in alphabetical order
with standard modules before add-in modules). The one exception is that
at times I use imports to make sure that certain modules are indeed
installed. For example, when I must have win32 modules I import like this:

import os
import sys
import time

try:
import win32api
except ImportError:
print "The win32 extensions must be installed!"
sys.exit()
 
G

Gekitsuu

That is part of what I was asking but I was also hoping to hear the
common wisdom so to speak. When I posted I had considered the idea for
a bit and the situations people have mentioned were similar to the
scenario I came up with as a good time to break such a rule. My
hypothetical situation was as follows. I'm writing a new generic SQL
module and I want to make it so I only call the appropriate module for
the type of SQL server I'm talking to. Then it would make sense to
load, for instance, the mysql module and not the sqlite, postgresql,
etc. But should it be part of the PEP to include what to do in a
situation were it makes sense to break the rule? Something like if an
import needs to be in a location other than the top of the module
because of conditions determining if it will be loaded, there should be
a comment at the top of the module where the other imports are declared
stating what is loaded, why it is elsewhere, and a general idea of
where it is. Something like..

# import mysql_module
# This is imported in the useMysql() function and is only imported if
needed

I looked for a way to make a suggestion to the PEP but it wasn't
obvious to me from the link how you'd do it.
 
F

Fredrik Lundh

Gekitsuu said:
That is part of what I was asking but I was also hoping to hear the
common wisdom so to speak. When I posted I had considered the idea for
a bit and the situations people have mentioned were similar to the
scenario I came up with as a good time to break such a rule. My
hypothetical situation was as follows. I'm writing a new generic SQL
module and I want to make it so I only call the appropriate module for
the type of SQL server I'm talking to. Then it would make sense to
load, for instance, the mysql module and not the sqlite, postgresql,
etc. But should it be part of the PEP to include what to do in a
situation were it makes sense to break the rule? Something like if an
import needs to be in a location other than the top of the module
because of conditions determining if it will be loaded, there should be
a comment at the top of the module where the other imports are declared
stating what is loaded, why it is elsewhere, and a general idea of
where it is. Something like..

# import mysql_module
# This is imported in the useMysql() function and is only imported if
needed

I looked for a way to make a suggestion to the PEP but it wasn't
obvious to me from the link how you'd do it.

the PEP has enough silly rules as it is; no need to add even more
sillyness.

(why would anyone interested in what your useMysql function is doing
waste any time reading comments at the top of the file ? you're over-
doing things. don't do that; that's not pythonic)

</F>
 
P

Peter Decker

My
hypothetical situation was as follows. I'm writing a new generic SQL
module and I want to make it so I only call the appropriate module for
the type of SQL server I'm talking to. Then it would make sense to
load, for instance, the mysql module and not the sqlite, postgresql,
etc.

You should take a look at the Dabo project. The dabo.db module take a
setting and imports just the required library for the chosen database.
It really isn't that difficult a concept to handle.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top