Skip to content

Instantly share code, notes, and snippets.

@dustinmm80
Last active December 18, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustinmm80/5694822 to your computer and use it in GitHub Desktop.
Save dustinmm80/5694822 to your computer and use it in GitHub Desktop.
Things to watch out for when coding in Python

Python Protips

A collection of tips from things I've seen in a lot of code bases.

Use print() as a function and not a statement

print('some string') # good
print 'some string'  # bad

print() has been moved to a function in Python 3 docs. It has been backported to 2.7.


Replace '' % (args) with ''.format(args)

'{0.name} {0.address} {0.city}'.format(k) # good
'%s %s %s' % (k.name, k.address, k.city)  # bad

String formatting with format() is replacing %. It is more powerful (argument unpacking, etc) and clear.


Make sure docstrings are using double quotes

def do(a, b, c): # good
	"""
	does something
	"""
	pass
	
def do(a, b, c): # bad
	'''
	does something
	'''
	pass

Docstrings with single quotes don't follow ReST format, and can't be picked up by Sphinx.


Make sure all other strings are single-quoted

quote = 'it isn\'t the gravity # good
quote = "it isn't the gravity" # bad

Single-quoted strings follows pep8, consistency is good across code base


Call functions with named parameters as often as possible

def rotate_head(x, y, z, reverse=False):
	pass
	
rotate_head(x=15, y=11, z=20, reverse=True) # good
rotate_head(15, 11, 20, True) 				 # bad

Sacrificing brevity for readability is okay in this case. Makes a big difference for code clarity.


Don't use mutable types or functions as default keyword args

def filter_gradient(x, y, colors=None, timestamp=None): # good
	if colors is None:
		colors = []
	if timestamp is None:
		timestamp = datetime.now()

def filter_gradient(x, y, colors=[], timestamp=datetime.now()): # bad
	pass

Default parameters are bound at function declaration, and not execution. In the bad example above, multiple calls to filter_gradients would mutate colors every time. For timestamp, datetime.now() is not called every time the function is invoked. So timestamp would be identical every time you called it.


Be careful about commenting out code, crufts up codebase

Let git keep your history for you; if you comment out a block of code, consider just removing it instead. If you need it back, you can retrieve it from the git history. This keeps your code clean and minimizes confusion.


Functions or classes w/ 5 or more args can probably be split up

In the case where you are passing 5+ args to a function, it is probably better to split it up into either smaller functions or use **kwargs. If you use **kwargs be sure to document what keyword arguments will change the execution of your function.

For classes that are keeping the state of many things, first of all think about whether this needs to be a class. If it is a singleton, you probably can namespace it at the module level. If it needs to be a class, breaking it up into smaller classes and composing it using multiple inheritance can help manage the complexity. It will also make testing easier.


Keep lines at 79 lines or less

From PEP8, lines in python should be 79 lines or less. Some devs whine about this, but if you have a line longer than 79 chars, you're probably trying to do too much in that line. Examples of this: complicated list comprehensions and appending long strings. List comprehensions should be simple (comprehendable) and ''.join(iterable) is the best way to join those strings. Each statement should read like a simple English sentence, not a paragraph or complex sentence.


Indent dicts and lists out, for readability

animals = ['tiger', 'bear', 'cat, 'dog', 'donkey', # bad, make this all one line, or indent so each item has its own line
'zebra', 'lion', 'wallaby', 'chipmunk']

# same with dicts, but even more so

animals = { # good indentation
	'name': 'tiger'
	'species': 'feline',
	'age': 10
}

For clarity, indent out your dicts and lists if they start to get long.


Use correct data structures - tuples, lists, dicts, sets, deques

A lot of data structures in Python can be used interchangably, but each is suited to a specific purpose.

dict - use when you have key:value pairs and order doesn't matter, use OrderedDict if order matters

set - use when you have homogenous items, they need to be unique, and order doesn't matter

list - use when you have homogenous items, order matters, and its size won't change much

tuple - use when position matters, heterogeneous items, and size never changes - can use namedtuple for clarity

deque - use when you would use a list, but you know you will be adding or removing elements from either end - much faster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment