473,396 Members | 1,945 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Beautiful Python

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.

Dec 26 '05 #1
8 1453
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).

--
Jarek Zgoda
http://jpa.berlios.de/
Dec 26 '05 #2
On Mon, 26 Dec 2005 02:01:07 -0800, Gekitsuu wrote:
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.
--
Steven.

Dec 26 '05 #3
On 2005-12-26 05:01:07 -0500, "Gekitsuu" <ge******@gmail.com> 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.


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

--
Chip Turner ct*****@pattern.net

Dec 26 '05 #4
Gekitsuu wrote:
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".

Dec 26 '05 #5
rbt
sc****@in-spec-inc.com wrote:
Gekitsuu wrote:
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.


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()

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".

Dec 27 '05 #6
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.

Dec 27 '05 #7
"Gekitsuu" wrote:
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>

Dec 27 '05 #8
On 27 Dec 2005 10:02:17 -0800, Gekitsuu <ge******@gmail.com> wrote:
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.

--

# p.d.
Dec 27 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: vinjvinj | last post by:
I haven't used an IDE in a long time but gave wing ide a try because I wanted the same development platform on Linux and Windows. I'm currently using Ultraedit and it works fine but needed...
3
by: Max | last post by:
I have a friend who has been programming in C for many years, and he is a great fan of the language. However, he (and I) are about to start a python course, and he has been asking me a lot of...
1
by: Tempo | last post by:
Heya. I have never used a module/script before, and the first problem I have run into is that I do not know how to install a module/script. I have downloaded Beautiful Soup, but how do I use it in...
0
by: Anthra Norell | last post by:
Hi, Martin, SE is a stream editor that does not introduce the overhead and complications of overkill parsing. See if it suits your needs: http://cheeseshop.python.org/pypi/SE/2.2%20beta ...
3
by: cjl | last post by:
I am learning python and beautiful soup, and I'm stuck. A web page has a table that contains data I would like to scrape. The table has a unique class, so I can use: soup.find("table",...
8
by: js | last post by:
Hi, Have you ever seen Beautiful Python code? Zope? Django? Python standard lib? or else? Please tell me what code you think it's stunning.
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.