Writing reusable code is a good thing, right? The trick is to do so in a way that makes your life and those of others easier, but to do so in a very clear and maintainable way. Recently I've been playing around with Python's functools.partial function, which I've found can help facilitate writing reusable code.

While the documentation has a nice explanation and demonstration of
`functools.partial`

, it's very serious. I've got my own internal
version of things which I think is a little more fun.

`functools.partial`

What `functools.partial`

does is:

- Makes a new version of a function with one or more arguments already filled in.
- New version of a function documents itself.

Rather than dive into paragraphs of explanation, I'll use code examples to explain how this works.

`functools.partial`

First, let's say we want to create a function that explicitly performs
exponentiation. This way
we can get the
squares,
cubes, and other power
operations on any number. This duplicates Python's built-in `pow()`

function, but our version has the very nice addition of keyword
arguments.

```
def power(base, exponent):
return base ** exponent
```

Now what if we want to have dedicated square and cube functions that
leverage the `power()`

function? Of course, we can do it thus:

```
def square(base):
return power(base, 2)
def cube(base):
return power(base, 3)
```

This works, but what if we want to create 15 or 20 variations of our
`power()`

function? What about 1000 of them? Writing that much
repetitive code is, needless to say, annoying. This is where partials
come into play. Let's rewrite our square and cube functions using
partials, and test it for success using
py.test:

```
from functools import partial
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
def test_partials():
assert square(2) == 4
assert cube(2) == 8
```

Whoa! That's awesome. You know what adds to that awesome? Functions created with partial document themselves (to a degree). I'll demonstrate with more tests:

```
def test_partial_docs():
assert square.keywords == {"exponent": 2}
assert square.func == power
assert cube.keywords == {"exponent": 3}
assert cube.func == power
```

Using a loop, let's build and test ten (10) custom `power()`

functions,
which I'll call 'power partials' (ahem... I find 'power partials'
sounds rather amusing.):

```
def test_power_partials():
# List to store the partials
power_partials = []
for x in range(1, 11):
# create the partial
f = partial(power, exponent=x)
# Add the partial to the list
power_partials.append(f)
# We could just use list comprehension instead of the loop
# [partial(power, exponent=x) for x in range(1, 11)]
# Test the first power
assert power_partials[0](2) == 2
# Test the fifth power
assert power_partials[4](2) == 32
# Test the tenth power
assert power_partials[9](2) == 1024
```

Lists are great, but sometimes it's nice to have a more legible way of interacting with functions. There are an infinite ways to make this happen, but I like the dot notation of classes. So here is a 'partial structure' class which follows a pattern I think is pretty handy:

```
# Since I like my article code to work in both Python 2.7 and 3,
# I'll import the excellent six library to manage the
# differences between Python versions. Six is available on PyPI
# at https://pypi.python.org/pypi/six.
from six import add_metaclass
class PowerMeta(type):
def __init__(cls, name, bases, dct):
# generate 50 partial power functions:
for x in range(1, 51):
# Set the partials to the class
setattr(
# cls represents the class
cls,
# name the partial
"p{}".format(x),
# partials created here
partial(power, exponent=x)
)
super(PowerMeta, cls).__init__(name, bases, dct)
@add_metaclass(PowerMeta)
class PowerStructure(object):
pass
```

Okay, let's test our PowerStructure class as an instantiated PowerStructure:

```
def test_power_structure_object():
p = PowerStructure()
# 10 squared
assert p.p2(10) == 100
# 2 to the 5th power
assert p.p5(2) == 32
# 2 to the 50th power
assert p.p50(2) == 1125899906842624
```

Looks good, right? But wait, there's more!

Thanks to the power of metaclasses, we don't need to instantiate the PowerStructure class!

```
def test_power_structure_class():
# Thanks to the power of metaclasses, we don't need to instantiate!
# 10 squared
assert PowerStructure.p2(10) == 100
# 2 to the 5th power
assert PowerStructure.p5(2) == 32
# 2 to the 50th power
assert PowerStructure.p50(2) == 1125899906842624
```

I've provided some simple examples of how to use `functools.partials`

.
I find them really useful for certain tasks, mostly in avoiding
repeating myself. Like any coding tool, complex usage can cloak the
meaning of code, so be careful and use `functools.partials`

judiciously.

Update: Nick Coghlan reminded me to
mention that Python has a `pow()`

built-in.

Update 04/30/2014: Samuel John corrected me on Nick Coghlan's name.

Published: 2014-04-24 09:00

Tags: python

If you read this far, you might want to follow me on twitter or github and subscribe via email below (I'll email you new articles when I publish them).

Two Scoops of Django

Two Scoops of Django is chock-full of material that will help you with your Django projects. Written to support Django 1.11 LTS (Long Term Support), this book won't get outdated until 2020.

python django pycon twoscoops howto book audrey class-based-views ppoftw rant holidays blog friends family djangocon python3 resolutions django-rest-framework capoeira travel forms eventbrite pypi hackathon api flask mongodb cheatsheet travel tips for geeks pycon-2013-guide testing argentina LaTeX europe ruby meme consumernotebook philippines pyladies setup tools cookiecutter javascript pypy pyramid i18n unicode pydiversity markdown heroku php clojure nodejs sprint LA review australia nasa Consumer-Notebook OAuth paypal europython joke WhartonWC jinja2 bottle halloween pumpkin ingredients recipe surgery barcamp packaging binstar conda faceoff RestructuredText brambles Cartwheel Web training Two Scoops Academy djangopackages Los Angeles lahackthons casestudy vs meteor perl la rails wsgi dsf djangodash functions science usability css lahackathons los-angeles postgresql mountain colombia coreapi Vue.js eskrima cryptocurrency bitcoin

If you read this far, you might want to follow me on twitter or github and subscribe via email below (I'll email you new articles when I publish them).

Content Copyright © 2012-2018 Daniel Greenfeld. Proudly harnessed by Mountain, powered by Flask, and rendered by Frozen Flask, all of which take great advantage of Python.

## Comments