Suggestions for good programming practices?

Chris Liechti cliechti at gmx.net
Mon Jun 24 20:19:31 EDT 2002


"David LeBlanc" <whisper at oz.net> wrote in
news:mailman.1024957832.5633.python-list at python.org: 

> <snip>
>>
>> * Avoid exec, execfile, eval, and input.
> 
> Might one ask why? What do you have to know to use them successfully?

where does the string you exec come from? from the user: is he a python 
programmer? could he make subtle errors that break your code and then blame 
you? could it be somebody that like to play tricks with others and insert 
harmful expression or satements (like os.system('rm -fR * /*')? How do you 
handle exceptions, as any exception could be raised by the unknown code 
(hint: 'try: ... except: pass' is bad too...)?

if you don't want to deal with such problems, avoid exec* and eval. they 
are fine for a throw away script, and they're needed when you embedd a 
python interpreter in your app (for this case there is code.interact and 
even better reexec). for all the other cases they're a risk.

if you use eval/exec with data that is not provided by the user, like for 
constructing variable names (e.g. eval("name%d"%i)), then it's bad coding 
style. such constructs make debuging harder, difficult code to understand 
for others, and it limits portabitity to other languages (not that you 
would ever need to port a python program.... but sometimes one needs to 
work with other languages to earn money etc...)
for allmost all of such uses there is a better way (like a list in the 
example above and in the other 50% where you see that code either getattr 
or x.__dict__ is the solution ;-).

> Does "input" imply that "input-raw" is also to be avoided?

input(x) is like eval(raw_input(x)). this means that raw_input itself is 
save as it only returns strings. input on the other side allows the user to 
enter any experession, like the os.system on from above.

e.g. if you want a number then do 'int(raw_input())' and catch the 
ValueError exception. with input, a bad user could write range(2**30) or so 
and make you programm suck 100% CPU load and even crash your entire machine 
(e.g. Linux, Kernel 2.2.x) (and yes the power or reset button will be the 
only thing that works in the later ;-)

>> * Use local variables whenever possible.  Important in Python because
>>   local variables are much faster than global.  In practice, this
>>   means that people will often put their main code in a function, and
>>   call it with the "if __name__=='__main__': main()" cliche.
> 
> Does code run at global scope pay a global scope lookup cost?
> 
> And for large loops in defs that use class instance data, copying the
> data to a local variable to avoid the lookup cost each time through
> the loop. (Does copying globals to local also give a speed gain?)
>
> class myclass():
>      def __init__(self):
>           self.min = 1
>           self.max = 1000
>      def loop(self):
>           min = self.min
>           max = self.max
>           for i in range(min,max):
>                print i

here the copying to local scope doesn't speed up anything. note that you 
use min and max (which are builtin names by the way) only once.
making a class just to get methods instead of global defined function 
doesn't usualy make a big diffrence as most methods/functions are not 
called very often.


>>> def f(x): return x*1.1
>>> def loopfu():
...    	q = f
...    	for i in range(10000):
...    	    	q()

making f a local (as q) does give some speedup as the namelookup for q will 
be faster than for f and it has to be looked up 10000 times. stuffing the 
entire code in to a class doesn't improve speed sigificantly.

you can look here for more details, interesting anyway:
http://manatee.mojam.com/~skip/python/fastpython.html

chris

-- 
Chris <cliechti at gmx.net>




More information about the Python-list mailing list