Skip to content

Instantly share code, notes, and snippets.

@rafaelmv
Last active November 25, 2015 01:15
Show Gist options
  • Save rafaelmv/ea84028aca06d4db516f to your computer and use it in GitHub Desktop.
Save rafaelmv/ea84028aca06d4db516f to your computer and use it in GitHub Desktop.

Python Super Powers

Argument Unpacking

In Python we can unpack a list or a dictionary as function arguments using * and **.

def print_numbers(x, y):
	print x
	print y

list = [1, 2]
dict = {'x': 1, 'y': 2}

print_numbers(*list)
print_numbers(**dict)

Decorators

Decorators allow to wrap a function or method in another function that can add functionality, modify arguments, results, etc. We write decorators one line above the function definition, beginning with "at" sign (@).

def print_args(fun):
	def wrapper(*args, **kwargs):
		print 'Arguments:', args, kwargs
		return fun(*args, **kwargs)
	return wrapper

@print_args
def write(text):
	print text

write('foo')

Default argunments

Warning with this

def foo(x=[]):
	x.append(1)
	print x

def foo(x=None):
	if x is None:
		x = []
	x.append(1)
	print x

Descriptors

They're the magic behind a whole bunch of core Python features.

When you use dotted access to look up a member (eg, x.y), Python first looks for the member in the instance dictionary. If it's not found, it looks for it in the class dictionary. If it finds it in the class dictionary, and the object implements the descriptor protocol, instead of just returning it, Python executes it. A descriptor is any class that implements the __get__, __set__, or __delete__ methods.

Here's how you'd implement your own (read-only) version of property using descriptors:

class Property(object):
	def __init__(self, fget):
		self.fget = fget

	def __get__(self, obj, type):
		if obj is None:
			return selfIt's great for things like adding up numbers:
		return self.fget(obj)

and you'd use it just like the built-in property():

class MyClass(object):
	@Property
	def foo(self):
		return "Foo!"

Descriptors are used in Python to implement properties, bound methods, static methods, class methods and slots, amongst other things. Understanding them makes it easy to see why a lot of things that previously looked like Python 'quirks' are the way they are.

Raymond Hettinger has an excellent tutorial that does a much better job of describing them than I do.

get() method in Dictionaries

Dictionaries have a 'get()' method. If you do d['key'] and key isn't there, you get an exception. If you do d.get('key'), you get back None if 'key' isn't there. You can add a second argument to get that item back instead of None.

It's great for things like adding up numbers:

sum[value] = sum.get(value, 0) + 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment