python worst practices

61
7/17/2019 python worst practices http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 1/61 Python Worst Practices Daniel Greenfeld

Upload: frankliu

Post on 08-Jan-2016

234 views

Category:

Documents


0 download

DESCRIPTION

Slide presentation by Daniel Greenfeld

TRANSCRIPT

Page 1: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 1/61

Python Worst PracticesDaniel Greenfeld

Page 2: python worst practices

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

Page 3: python worst practices

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!

Page 4: python worst practices

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

Page 5: python worst practices

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 

Page 6: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 6/61

Fundamentals

Page 7: python worst practices

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

Page 8: python worst practices

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

Page 9: python worst practices

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

Page 10: python worst practices

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

Page 11: python worst practices

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

Page 12: python worst practices

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

Page 13: python worst practices

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

Page 14: python worst practices

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

Page 15: python worst practices

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

Page 16: python worst practices

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"

Page 17: python worst practices

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

Page 18: python worst practices

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"

Page 19: python worst practices

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"

Page 20: python worst practices

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

Page 21: python worst practices

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

Page 22: python worst practices

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

Page 23: python worst practices

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 

Page 24: python worst practices

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 

Page 25: python worst practices

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 

Page 26: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 26/61

Classes

D l G f ld

Page 27: python worst practices

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

Page 28: python worst practices

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

Page 29: python worst practices

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

Page 30: python worst practices

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

Page 31: python worst practices

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

Page 32: python worst practices

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

Page 33: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 33/61

Exceptions

Daniel Greenfeld

Page 34: python worst practices

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

Page 35: python worst practices

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

Page 36: python worst practices

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)

Page 37: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 37/61

Getting controversial

Daniel Greenfeld

Page 38: python worst practices

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

Page 39: python worst practices

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

Page 40: python worst practices

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

Page 41: python worst practices

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

Page 42: python worst practices

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

Page 43: python worst practices

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

Page 44: python worst practices

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

Page 45: python worst practices

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

Page 46: python worst practices

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

Page 47: python worst practices

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

Page 48: python worst practices

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

Page 49: python worst practices

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

Page 50: python worst practices

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

Page 51: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 51/61

Documentation

Daniel Greenfeld@pydanny

Page 52: python worst practices

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

Page 53: python worst practices

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

Page 54: python worst practices

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

Page 55: python worst practices

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

Page 56: python worst practices

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

Page 57: python worst practices

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

Page 58: python worst practices

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

Page 59: python worst practices

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

Page 60: python worst practices

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!

Page 61: python worst practices

7/17/2019 python worst practices

http://slidepdf.com/reader/full/python-worst-practices-568f5d3821323 61/61

Questions?