This document discusses various Python anti-patterns and better practices for writing clean Python code. It provides examples of bad practices like catching all exceptions, not using enumerate() or zip() when iterating over multiple lists, and string concatenation for formatting. Better alternatives shown include specifying exception types, using enumerate() and zip(), and string formatting methods. The document also recommends using context managers, generators, unpacking values, and the any() and all() built-in functions.
7. Butaccording to Python Style Guide, parentheses are preferred:
BREAKING LONG LINES
This is possible:
ifais"somevalue"
andbis"someothervalue"
andcisnot"thisothervalue":
pass
if(ais"somevalue"
andbis"someothervalue"
andcisnot"thisothervalue"):
pass
8. Better:
USE CONTEXT MANAGERS
Mostnotably, for open()
f=open('file.txt','r')
printf.read()
f.close()
withopen('file.txt','r')asf:
printf.read()
The file willalways be properlyclosed
"contextmanagers provide __enter__() and __exit__()
methods thatare invoked on entryto and exitfrom the
bodyof the with statement."
10. Shorter (and cleaner)
USING LIST COMPREHENSION
colors=['blue','green','yellow','red','brown','black']
x=[]
foritemincolors:
if'e'initem:
x.append(item)
>>>x
['blue','green','yellow','red']
>>>[cforcincolors]
['blue','green','yellow','red','brown','black']
>>>[cforcincolorsif'e'incolor]
['blue','green','yellow','red']
>>>[c.upper()forcincolorsif'e'incolor]
['BLUE','GREEN','YELLOW','RED']
no nested loop necessary
more concise
11. OR DICT COMPREHENSION, FOR THAT
MATTER
colors=['blue','green','yellow','red','brown','black']
>>>dict([(c,len(c))forcincolors])
{'blue':4,'brown':5,'yellow':6,'green':5,'black':5,'red':3}
#isthesameas
>>>{c:len(c)forcincolors}
{'blue':4,'brown':5,'yellow':6,'green':5,'black':5,'red':3}
12. Instead, write
USING EXPLICIT FALSE
Values thatare considered false are:
None
False
Zero of anynumeric type
Anyemptycontainer, e.g. '',(),[],{}
So, this is unnecessary:
iflen(some_list)>0:
...
ifinteger_value<1:
...
ifsome_list:
...
ifnotinteger_value:
...
Does notapplyto sets!
13. CHECKING FOR NONE TYPES
BAD:
ifobj==None:
...
ifobj!=None:
...
ifnotobj==None:
...
"Comparisons to singletons like None should always
be done with is or is not, never the equalityoperators." (PEP8)
Classes are free to implementcomparison.
So __eq__() or __cmp__() can be defined in anyway
So playsafe - compare objectidentities using is
also, is is faster!
ifobjisNone:
...
ifobjisnotNone:
...
15. Applies to listcomprehension:Generator expression
USING GENERATOR FUNCTIONS
Possible
defget_numbers():
data=[]
foreachinget_data():
ifeach>10:
data.append(each)
returndata
Possiblybetter
defget_numbers():
foreachinget_data():
ifeach>10:
yieldeach
>>>data_generator=(dfordinget_data()ifd>10)
printdata_generator
<generatorobject<genexpr>at0x3027640>
>>>foriindata_generator:
>>>...printi
[11,12,13]
16. When you can do this:
UNPACKING VALUES
Whydo this:
>>>do_something()
('Operationsucceeded',True)
>>>values=do_something()
message=values[0]
success=values[1]
>>>message,success=do_something()
printmessage,success
OperationsucceededTrue