469,280 Members | 1,855 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,280 developers. It's quick & easy.

Good code patterns in Python

If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value

Why?

Because those people reusing your code might decide to
change or adapt the "if" part of the first example. Or
the "else" part for that matter. And then they could end
up with "some_name" being undefined, crashing other code
maybe 1000's of lines away. This could happen for example
because they use exceptions in the "if" part that jump out
of it, etc.

There is the small overhead of assigning something twice
to some_name in the safer example, so if performance is
*that* important then the first example is better, but I
feel there should be comments with warnings around it:
**CREATING A NEW OBJECT REFERENCE HERE!** Hmm, now that
makes code ugly :-)

What are your thoughts about this? I am interested in
current large scale software development practice, and
guidelines that are used there, especially for dynamically
typed languages like Python.

There must be a lot of advisable code design patterns (I
can't find a good name in English) like this for use in
software development with many programmers. Perhaps a
collection with good documentation would be interesting?
Or a tool like pychecker that flags "bad" patterns?
--
People who miss goto now use exceptions
Jul 18 '05 #1
12 2311

"Will Stuyvesant" <hw***@hotmail.com> wrote in message
news:cb**************************@posting.google.c om...
If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value
If, bool(some_value) == True, I personally would use the near-ternary
idiom

some_name = some_condition and some_value or other_value

(or equivalent form for bool(other_value)== True or either == False).

This is both safe and efficient, avoiding both
Because those people reusing your code might decide to
change or adapt the "if" part of the first example. Or
the "else" part for that matter. And then they could end
up with "some_name" being undefined, crashing other code
maybe 1000's of lines away.
and
There is the small overhead of assigning something twice


(I acknowledge that some think this ugly and worse and would not be
caught dead writing such an 'abomination', so flame repetition is not
necessary ;-)

Terry J. Reedy
Jul 18 '05 #2
One, there has been a proposal for a ternary operator on python.org. You
know that kind of (cond) ? (eval1) : (eval2) stuff.

Two, no need to guard that code. Passing and assigning a paramater should
always make you THINK about what's happening.

Three, how about
a = 1
b = 0
......
if b == 0:
a = 0
else:
a = a/b
? You cannot replace it with your pattern. Sure enough, there are far more
examples of this -- when you cannot evaluate the first expression.

Jiri Barton


Jul 18 '05 #3
Quoth Will Stuyvesant:
If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value
I join the Ms in disagreeing strongly. The visual parallelism of
the first reflects the conceptual parallelism of the two cases,
while the second obscures it.
Because those people reusing your code might decide to
change or adapt the "if" part of the first example. Or
the "else" part for that matter. And then they could end
up with "some_name" being undefined, crashing other code
maybe 1000's of lines away. This could happen for example
because they use exceptions in the "if" part that jump out
of it, etc.
I assume you're not speaking of local variables here -- a function
thousands of lines long would be unconscionable.

Presumably you're speaking of attributes, and the danger is that
an exception in one branch would cause the object's invariants be
broken. But I don't see how this would happen in practice, in a
way which would (a) leave the attribute undefined and (b) imply to
the caller that everything was fine. Do you have an example?

(Much more serious and more common is the danger that after an
exception is raised, the function has done half its work and left
the object in a broken state. But this has nothing to do with
what you're talking about.)
There is the small overhead of assigning something twice


Too minor to worry about:

$ timeit -s'def foo(): global a; a = 1' 'foo()'
100000 loops, best of 3: 5.51 usec per loop
$ timeit -s'def foo(): global a; a = 1; a = 1' 'foo()'
100000 loops, best of 3: 6.1 usec per loop

If I'm running the code a million times, and everything else in
the loop takes less than a microsecond, this might be worth
thinking about.

--
Steven Taschuk w_w
st******@telusplanet.net ,-= U
1 1

Jul 18 '05 #4
|h****@hotmail.com (Will Stuyvesant) wrote:
|> if some_condition:
|> some_name = some_value
|> else:
|> some_name = other_value
|> is often a mistake. Much better, safer, would be:
|> some_name = some_value
|> if not some_condition:
|> some_name = other_value

mi**@pitt.edu (Michele Simionato) wrote previously:
|I am sorry, but I feel that the first form is MUCH more readable than the
|second one; the first form is crystal clear to me, whereas I must read
|the second form two or three times to understand what it is going on.

Moreover, actual code often assigns from computations, not simply one
name to another. The harder-to-read form risks bad side effects (or
simply a performance hit):

some_name = some_computation()
if not some_condition:
some_name = other_computation()

The straightforward if/else form avoids superfluous computations.

Yours, Lulu...

--
mertz@ _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis _/_/ Postmodern Enterprises _/_/ s r
..cx _/_/ MAKERS OF CHAOS.... _/_/ i u
_/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/ g s
Jul 18 '05 #5
Will Stuyvesant fed this fish to the penguins on Tuesday 01 July 2003
02:49 am:

some_name = some_value
if not some_condition:
some_name = other_value
Ugh... Shades of old BASIC...

10 sn = sv
20 if sc then 40
30 sn = ov
40 ...

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #6
Will Stuyvesant <hw***@hotmail.com> wrote:
If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value

Why?
My personal opinion is that it depends on context. The first idiom
is more clear when you are dealing with some kind of a switch. The
second idiom works better if you have a default value that needs to be
overridden in some cases.
Because those people reusing your code might decide to
change or adapt the "if" part of the first example. Or
the "else" part for that matter. And then they could end
up with "some_name" being undefined, crashing other code
maybe 1000's of lines away. This could happen for example
because they use exceptions in the "if" part that jump out
of it, etc.
Of course, another alternative is to combine both approaches by setting
a default value:

#set default for some_value
some_value = []
if condition1:
some_value = function1()
else:
some_value = function2()

And then if you really want to be safe the functions using
some_value should do reality checks as well.
def function3(some_value=[]):
if len(some_value):
do something
else:
do something else.

I think that an argument for the readability of if-else is that because
the logic is made more clear, it can be more effectively replaced.

There is the small overhead of assigning something twice
to some_name in the safer example, so if performance is
*that* important then the first example is better, but I
feel there should be comments with warnings around it:
**CREATING A NEW OBJECT REFERENCE HERE!** Hmm, now that
makes code ugly :-)


The problem here is that ***creating a new object reference*** is not
only ugly, but its ambiguous as well. (What kind of object, what is it
used for?) If indeed some_name is an important variable in your program,
then provide a full description.

#some_value (string) is used to hold the widgit that will
#be passed to a wadget and eventually passed
#to standard output.

--
Kirk Job-Sluder
http://www.jobsluder.net/~kirk/

Jul 18 '05 #7
Kirk Job-Sluder wrote:
Will Stuyvesant <hw***@hotmail.com> wrote:
If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value

Why?


My personal opinion is that it depends on context. The first idiom
is more clear when you are dealing with some kind of a switch. The
second idiom works better if you have a default value that needs to be
overridden in some cases.


I presume the "mistake" he's referring to with the first snippet is the
potential problem that could happen if the variable is named
incorrectly:

if condition:
variable = someValue
else:
varaible = otherValue # [sic] note the typo!

When you really want an atomic assignment of one singular variable. The
complete solution to this would probably be a conditional expression,
e.g.:

variable = (if condition: someValue else: otherValue)

eliminating the duplication which can lead to errors. (Python, of
course, doesn't have such a construct, and the silence after the
conditional expression PEP vote and the long silence thereafter suggests
that it never will.)

I still don't think this significant of a risk to warrant widespread
conversion of statements to the form Will suggests, especially when you
have things like PyChecker that can check for (probable) typos. It's a
slightly unfortunate wart in dynamic languages without conditional
operators, but I don't think it rises to the level of something that
should be corrected via such (what seems to me) a heavy-handed style.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ When the solution is simple, God is answering.
\__/ Albert Einstein
Jul 18 '05 #8
Erik Max Francis <ma*@alcyone.com> writes:
The
complete solution to this would probably be a conditional expression,
e.g.:

variable = (if condition: someValue else: otherValue)

eliminating the duplication which can lead to errors. (Python, of
course, doesn't have such a construct, and the silence after the
conditional expression PEP vote and the long silence thereafter suggests
that it never will.)


Guido broke his silence at EuroPython: The ternary operator will not be
added to Python.

Bernhard

--
Intevation GmbH http://intevation.de/
Sketch http://sketch.sourceforge.net/
MapIt! http://www.mapit.de/
Jul 18 '05 #9
Bernhard Herzog wrote:
Guido broke his silence at EuroPython: The ternary operator will not
be
added to Python.


As I said, it's hardly a big surprise.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Divorces are made in Heaven.
\__/ Oscar Wilde
Jul 18 '05 #10
On Wed, 2 Jul 2003 15:43:33 +0200, holger krekel wrote:
Actually Guido made it pretty clear that he will be very careful about
adding language features especially at the syntax level.


Thank goodness the Boolean type made it in, then. (Not a syntax-level
change, but still a pretty fundamental one.)

--
\ "First they came for the verbs, and I said nothing, for verbing |
`\ weirds language. Then, they arrival for the nouns and I speech |
_o__) nothing, for I no verbs." -- Peter Ellis |
http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B
Jul 18 '05 #11
Bernhard Herzog wrote:
Guido broke his silence at EuroPython: The ternary operator will not
be
added to Python.


As I said, it's hardly a big surprise.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Divorces are made in Heaven.
\__/ Oscar Wilde
Jul 18 '05 #12
On Wed, 2 Jul 2003 15:43:33 +0200, holger krekel wrote:
Actually Guido made it pretty clear that he will be very careful about
adding language features especially at the syntax level.


Thank goodness the Boolean type made it in, then. (Not a syntax-level
change, but still a pretty fundamental one.)

--
\ "First they came for the verbs, and I said nothing, for verbing |
`\ weirds language. Then, they arrival for the nouns and I speech |
_o__) nothing, for I no verbs." -- Peter Ellis |
http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B
Jul 18 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

24 posts views Thread by matty | last post: by
13 posts views Thread by John Salerno | last post: by
4 posts views Thread by Carl J. Van Arsdall | last post: by
24 posts views Thread by John Salerno | last post: by
6 posts views Thread by Gabriel Genellina | last post: by
2 posts views Thread by dotnet dude | last post: by
1 post views Thread by =?ISO-8859-1?Q?Michael_Bernhard_Arp_S=F8rensen?= | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.