python worst practices
DESCRIPTION
Slide presentation by Daniel GreenfeldTRANSCRIPT
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 1/61
Python Worst PracticesDaniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 2/61
Daniel Greenfeld@pydanny
I do cartwheels
Daniel Greenfeld (@pydanny)
Pythonista at Cartwheel
Djangonaut at Revsys
Co-lead of Django Packages &
Open Comparison
Learned Python at NASA
Fiancé of Audrey Roy
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 3/61
Daniel Greenfeld@pydanny
Talk Format
• At least one ‘Python Worst Practice’ slide
• At least one ‘Fixed Python Practice’ slide
•A side-by-side comparison slide
Each section will have three components:
These slides are already online!
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 4/61
Daniel Greenfeld@pydanny
Warning!
Don’t use the‘Python Worst Practices’
examples in your code*
You may be hunted down and killed
*Sometimes these are caught byvarious code checking tools
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 5/61
Daniel Greenfeld@pydanny
Advice!
Do consider using the‘Fixed Python Practices’
examples in your code
You may get complimented
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 6/61
Fundamentals
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 7/61
Daniel Greenfeld@pydanny
Python Worst Practice
object = MyObject()map = Map()
zip = 90213 # common US developer mistakeid = 34 # I still fight this one
I’m guilty
• I still use ‘id’ when I shouldn’t
• I admit I have a problem
•That gives me license to pick on others
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 8/61
Daniel Greenfeld@pydanny
Fixed Python Practice
obj = MyObject() # necessary abbreviationobject_ = MyObject() # Underscore so we don't overwrite
map_obj = Map() # combine name w/necessary abbreviationmap_ = Map()
zip_code = 90213 # Explicit name with US focuspostal_code = 90213 # i18n explicit namezip_ = 90213
pk = 34 # pk is often synonymous with idid_ = 34
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 9/61
Daniel Greenfeld@pydanny
Side-by-side comparison
object = MyObject()
map = Map()zip = 90213 # common US developer mistake
id = 34 # I still fight this one
obj = MyObject() # Use a necessary abbreviation
object_ = MyObject() # Use underscore so we don't overwrite
map_obj = Map() # combine name with necessary abbreviationmap_ = Map()
zip_code = 90213 # Explicit name with US focus
postal_code = 90213 # International explicit namezip_ = 90213
pk = 34 # pk is often synonymous with id
id_ = 34
Worst Practice Fixed Practice
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 10/61
Daniel Greenfeld@pydanny
Python Worst Practice
true = 0
false = 1True = False
Flipping the booleans
Usually done to support an API
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 11/61
Daniel Greenfeld@pydanny
This sort of API
def crazy_posting_api(value): """ If a value is supplied
successfully return ‘0’. Otherwise return ‘1’ """
if value:
return 0 return 1
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 12/61
Daniel Greenfeld@pydanny
Fixed Python Practice
class CrazyApiConsumer(object):
def __init__(self, value): self.value = value
def post(self): # fix booleans in/around the return statement response = crazy_posting_api(self.value) return not bool(response)
cac1 = CrazyApiConsumer("hello")print(cac1.post())cac2 = CrazyApiConsumer("")print(cac2.post())
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 13/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
true = 0
false = 1True = False
class CrazyApiConsumer(object):
def __init__(self, value):
self.value = value
def post(self): # fix booleans in/around the return statement
response = crazy_posting_api(self.value) return not bool(response)
cac1 = CrazyApiConsumer("hello")
print(cac1.post())cac2 = CrazyApiConsumer("")
print(cac2.post())
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 14/61
Daniel Greenfeld@pydanny
Python Worst Practice
strColor = "green"boolActive = False
intPythonYears = 20
dtPythonFirstUsed = "04/20/2011"
Identifying variable types with prefixes
Mixing case doesn’t help either
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 15/61
Daniel Greenfeld@pydanny
Python Worst Practice
clr = "green"ctv = False
pythnYrs = 20
pthnFrstSd = "04/20/2011"
Conserving pixels by removing the vowels
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 16/61
Daniel Greenfeld@pydanny
Python Worst Practice
c = "green"a = False
p = 20
t = "04/20/2011"
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 17/61
Daniel Greenfeld@pydanny
Fixed Python Practicecolor = "green"
active = Falsepython_years = 20
python_first_used = "04/20/2011"
Python assumes we are all consenting adults
• Infer from naming schemes the type/purpose
• Don’t be constrained by type
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 18/61
Daniel Greenfeld@pydanny
Fixed Python Practice
The pixel shortage is over.Use reasonably long variable names.
color = "green"
active = Falsepython_years = 20
python_first_used = "04/20/2011"
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 19/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
strColor = "green"boolActive = FalseintPythonYears = 20
dtPythonFirstUsed = "04/20/2011"
clr = "green"
ctv = FalsepythnYrs = 20
pthnFrstSd = "04/20/2011"
c = "green"
a = Falsep = 20
t = "04/20/2011"
color = "green"active = False
python_years = 20python_first_used = "04/20/2011"
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 20/61
Daniel Greenfeld@pydanny
Python Worst Practice
foo = [1, 2, 3]
for i, item in zip(range(len(foo)), foo):
print i, item
Don’t use enumerate
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 21/61
Daniel Greenfeld@pydanny
Fixed Python Practice
Use enumerate
foo = [1, 2, 3]
for i, item in enumerate(foo):
print i, item
• Memorize the Python built-ins
• Makes your code easier to read
• Proven code
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 22/61
Daniel Greenfeld@pydanny
Side-by-side comparison
foo = [1, 2, 3]
zip(range(len(foo)), foo):
print i, item
foo = [1, 2, 3]
for i, item in enumerate(foo):
print i, item
Worst Practice Fixed Practice
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 23/61
Python Worst Practice
Pr ! ent using
Di " erent Fonts
Dark Text Dire Backgr # nds
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 24/61
Daniel Greenfeld@pydanny
Python Worst Practice
Present using
High ContrastEasy-to-read fonts
All devices off All programs off
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 25/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
Pr ! ent using Di " erent Fonts
Dark Text Dire Backgr # nds
Present using
High ContrastEasy-to-read fonts
All devices off
All programs off
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 26/61
Classes
D l G f ld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 27/61
Daniel Greenfeld@pydanny
Python Worst PracticeImplementing Java-style getters and setters
import logginglog = logging.getLogger()
class JavaStyle: """ Quiz: what else am I doing wrong here? """
def __init__(self): self.name = ""
def get_name(self): return self.name
def set_name(self, name):
log.debug("Setting the name to %s" % name) if isinstance(name, str): self.name = name else: raise TypeError()
if __name__ == "__main__": j = JavaStyle() j.set_name("pydanny did this back in 2006!")
print(j.get_name())
D i l G f ld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 28/61
Daniel Greenfeld@pydanny
Fixed Python PracticePython properties!
import logginglog = logging.getLogger()
class PythonStyle(object):
def __init__(self): self._name = ""
@property def name(self): return self._name
@name.setter def name(self, value):
""" Because name is probably a string we'll assume that we can infer the type from the variable name""" log.debug("Setting the name to %s" % value) self._name = value
if __name__ == "__main__": p = PythonStyle() p.name = "pydanny doing it the right way" print(p.name)
Accessor
Mutator
D i l G f ld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 29/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
import logginglog = logging.getLogger()
class JavaStyle: """ Quiz: what else am I doing wrong here? """
def __init__(self): self.name = ""
def get_name(self): return self.name
def set_name(self, name):
log.debug("Setting the name to %s" % name) if isinstance(name, str): self.name = name else: raise TypeError()
if __name__ == "__main__": j = JavaStyle() j.set_name("pydanny did this back in 2006!") print(j.get_name())
import logginglog = logging.getLogger()
class PythonStyle(object):
def __init__(self): self._name = ""
@property def name(self): return self._name
@name.setter
def name(self, value): """ Because name is probably a string we'll assume that we can infer the type from the variable name""" log.debug("Setting the name to %s" % value) self._name = value
if __name__ == "__main__": p = PythonStyle() p.name = "pydanny doing it the right way" print(p.name)
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 30/61
Daniel Greenfeld@pydanny
Python Worst Practice
class WebService(object):
@property def connect(self): self.proxy = xmlrpc.Server("http://service.xml")
if __name__ == '__main__':
ws = WebService() ws.connect
Using property setters as action methods!
A.K.A. Trying to make your Python code look like Ruby
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 31/61
Daniel Greenfeld@pydanny
Fixed Python Practice
class WebService(object):
def connect(self): self.proxy = xmlrpc.Server("http://service.xml")
if __name__ == '__main__':
ws = WebService()
ws.connect()
Methods please!
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 32/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
class WebService(object):
@property def connect(self): self.proxy = xmlrpc.Server("http://service.xml")
if __name__ == '__main__':
ws = WebService()
ws.connect
class WebService(object):
def connect(self):
self.proxy = xmlrpc.Server("http://service.xml")
if __name__ == '__main__':
ws = WebService()
ws.connect()
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 33/61
Exceptions
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 34/61
Daniel Greenfeld@pydanny
Python Worst Practice
try:
do_akshun(value)except: pass
Passing Generic Exceptions silently
• Ignorance is not bliss
• You have no idea what your system is doing
•Arguably better to not have this in your code
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 35/61
Daniel Greenfeld@pydanny
Fixed Python PracticeUse specific exceptions and/or logging
class AkshunDoesNotDo(Exception): """ Custom exceptions makes for maintainable code """
pass
try: do_akshun(value)except AttributeError as e:
log.info("Can I get attribution for these slides?") do_bakup_akshun(vlue)except Exception as e: log.debug(str(e)) raise AkshunDoesNotDo(e)
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 36/61
Daniel Greenfeld@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
try:
do_akshun(value)
except: pass
class AkshunDoesNotDo(Exception):
""" Custom exceptions makes for maintainable code """
pass
try:
do_akshun(value)except AttributeError as e:
log.info("Can I get attribution for these slides?") do_bakup_akshun(vlue)
except Exception as e: log.debug(str(e))
raise AkshunDoesNotDo(e)
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 37/61
Getting controversial
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 38/61
@pydanny
Python Worst Practice
• Hard to debug
• Security risk
• Sets bad precedents
imports = "from {0} import {1}".format("random", "randrange")exec(imports)
print(randrange(10))
Using exec for dynamic imports
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 39/61
@pydanny
Fixed Python Practice
• importlib is in the standard library
• Really explicit
• Direct tie into the Python machinery
import importlibfunstuff = importlib.import_module('random')
print(funstuff.randrange(10))
Using importlib for dynamic imports
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 40/61
@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
imports = "from {0} import {1}".format("random", "randrange")
exec(imports)print(randrange(10))
import importlib
funstuff = importlib.import_module('random')print(funstuff.randrange(10))
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 41/61
@pydanny
Python Worst Practice
• Too many characters on one line
• Lambdas by design does not have docstrings
• Does not necessarily mean less characters
• I can’t get this sample to work!
swap = lambda a, x, y: lambda f = a.__setitem__: (f(x, (a[x], a[y])), f(y, a[x][0]), f(x, a[x][1]))()
Generally using lambdas
Daniel Greenfeld
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 42/61
@pydanny
Fixed Python Practice
• Doc strings that show up nicely in help/Sphinx
• Easier to read
• In Python, functions are first class objects
• Whenever possible avoid using lambdas
def swap(a, x, y): """ Swap two position values in a list """ a[x],a[y] = a[y],a[x]
Daniel Greenfeld@ d
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 43/61
@pydanny
Side-by-side comparisonWorst Practice Fixed Practiceswap = lambda a, x, y:
lambda f = a.__setitem__: (f(x, (a[x], a[y])),
f(y, a[x][0]), f(x, a[x][1]))()
def swap(a, x, y):
""" Swap two position values in a list """ a[x],a[y] = a[y],a[x]
Daniel Greenfeld@ d
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 44/61
@pydanny
Python Worst Practice
• You can’t convince me that XML is the better way
• You are forcing me to learn a new language
<pydanny-ml> <do action="call_view">com.pydanny.nextSlide</do> <global name="spam" value="eggs" /></pydanny-ml>
Configuring your project with XML
Daniel Greenfeld@ d
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 45/61
@pydanny
Fixed Python Practice
• Is this the right way?
• This allows conditional logic
• Iterators
• i.e. “Magic Configuration”
spam = "eggs"actions = [ ('call_view', 'com.pydanny.nextSlide')
]
Use Python for configuration!
?
Daniel Greenfeld@ d
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 46/61
@pydanny
Python Worst Practice
INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdir(p)]MIDDLEWARE_CLASSES = [...]def callback(arg, dirname, fnames):
if 'middleware.py' in fnames: m = '%s.middleware' % os.path.split(dirname)[-1] MIDDLEWARE_CLASSES.append(m)
urlpatterns = patterns('', ...)for app in settings.INSTALLED_APPS: if not app.startswith('django'): p = url('^%s/' % app, include('%s.urls') % app) urlpatterns += patterns('', p)
‘Magical configuration code’
Ugh.
http://www.slideshare.net/jacobian/the-best-and-worst-of-django
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 47/61
@pydanny
Fixed Python PracticePREREQ_APPS = [ # Django "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.humanize", "django.contrib.flatpages",
# external "notification", # must be first "staticfiles", "uni_form",
... ]
urlpatterns = patterns("",
url(r"^$", homepage, name="home"), url(r"^accounts/", include("accounts.urls")), url(r"^admin/", include(admin.site.urls)), url(r"^about/", include("about.urls")), url(r"^profiles/", include("profiles.urls")), url(r"^notices/", include("notification.urls")), ... )
MIDDLEWARE_CLASSES = [ "django.middleware.common.CommonMiddleware", "django.contrib.sessions.middleware.SessionMiddleware" , "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware" , "reversion.middleware.RevisionMiddleware", "django.contrib.messages.middleware.MessageMiddleware" ,
... ]
Explicit is betterthen Implicit
This isn’t that much typing, is it?
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 48/61
@pydanny
Fixed Python PracticePREREQ_APPS = [ # Django "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites",
"django.contrib.messages", "django.contrib.humanize", "django.contrib.flatpages",
# external "notification", # must be first "staticfiles", "uni_form",
... ]
urlpatterns = patterns("",
url(r"^$", homepage, name="home"), url(r"^accounts/", include("accounts.urls")), url(r"^admin/", include(admin.site.urls)), url(r"^about/", include("about.urls")), url(r"^profiles/", include("profiles.urls")), url(r"^notices/", include("notification.urls")), ... )
MIDDLEWARE_CLASSES = [ "django.middleware.common.CommonMiddleware", "django.contrib.sessions.middleware.SessionMiddleware" , "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware" , "reversion.middleware.RevisionMiddleware", "django.contrib.messages.middleware.MessageMiddleware" , ... ]
Python’s design is predicated on the proposition thatcode is more often read than written.
http://www.slideshare.net/jacobian/the-best-and-worst-of-django/44
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 49/61
@pydanny
Fixed Python PracticeUse a config file
spam = "eggs"
[actions]
call_view = com.pydanny.nextSlide
Read up on config parser
http://docs.python.org/library/configparser.html
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 50/61
@pydanny
Side-by-side comparisonWorst Practice Fixed Practice
XML
logic heavy python
simple python files
config (.cfg) files
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 51/61
Documentation
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 52/61
@pydanny
Python Worst PracticeBad docstrings
• Do really obvious objects require doc strings?
• Complex methods require more than docstrings!
class Pythonista(): # Old style class! """ This class represents a Python programmer """
def code(self): """Write some code """ code, inspiration = Code(), Inspiration() for hour in Effort(): try: code += hour + inspiraion
except CurseWorthyBug: ...
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 53/61
@py a y
Fixed Python Practiceclass Pythonista(object):
def code(self): """ Writes code following these steps 1. Create a space for coding
2. Get some inspiration 3. Loop through some hours of effort 4. Write some code 5. Pull out hair cause of bugs """ code = Code()
inspiration = Inspiration() for hour in Effort(): try: code += hour + inspiraion except CurseWorthyBug: ...
Spend afew minutesdocumenting
the criticalstuff, okay?
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 54/61
@py y
Side-by-side comparison
class Pythonista(): # Old style class!
""" This class represents a Python programmer """
def code(self): """Write some code """
code, inspiration = Code(), Inspiration() for hour in Effort():
try: code += hour + inspiraion
except CurseWorthyBug:
...
class Pythonista(object):
def code(self):
""" Writes code following these steps 1. Create a space for coding
2. Get some inspiration 3. Loop through some hours of effort
4. Write some code 5. Pull out hair cause of bugs
"""
code = Code() inspiration = Inspiration() for hour in Effort():
try: code += hour + inspiraion
except CurseWorthyBug: ...
Worst Practice Fixed Practice
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 55/61
@py y
Python Worst Practice
• Generally not version controlled
•Backups? Mirrors?
• Editing via the web? Ugh.
• No pull requests - smaller group of contributors
Using a wiki for project documentation
“Wikis are where project documentation goes to die” Jacob Kaplan-Moss
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 56/61
py y
Fixed Python Practice
• Use Restructured Text
• Use Sphinx
• Host on http://readthedocs.org
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 57/61
Side-by-side comparisonWorst Practice Fixed Practice
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 58/61
Python Worst Practice
http://pypi.python.org/pypi/that
>>> import thatThe Anti-Zen of Python, by Daniel Greenfeld
Ugly is better than beautiful.Implicit is better than explicit.Complicated is better than complex.Complex is better than simple.Nested is better than flat.
Dense is better than sparse.Line code counts.Special cases are special enough to break the rules.Although purity beats practicality.Errors should always pass silently.Spelchek iz fur loosers.In the face of explicity, succumb to the temptation to guess.There should be many ways to do it.Because only a tiny minority of us are Dutch.Later is the best time to fix something.If the implementation is hard to explain, it's a good sell.If the implementation is easy to explain, it won't take enough time to do.Namespaces are too hard, just use import *!
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 59/61
Fixed Python Practice>>> import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.
Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!
Core Python
Daniel Greenfeld@pydanny
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 60/61
Side-by-side comparisonWorst Practice Fixed Practice
>>> import thatThe Anti-Zen of Python, by Daniel Greenfeld
Ugly is better than beautiful.
Implicit is better than explicit.Complicated is better than complex.Complex is better than simple.Nested is better than flat.Dense is better than sparse.Line code counts.Special cases are special enough to break the rules.Although purity beats practicality.Errors should always pass silently.
Spelchek iz fur loosers.In the face of explicity, succumb to the temptation to guess.There should be many ways to do it.Because only a tiny minority of us are Dutch.Later is the best time to fix something.If the implementation is hard to explain, it's a good sell.If the implementation is easy to explain, it won't take enough time to do.Namespaces are too hard, just use import *!
>>> import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.
Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.
Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!
7/17/2019 python worst practices
http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 61/61
Questions?