Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Python Partials

DZone's Guide to

Python Partials

Python comes with a fun module called functools. One of its classes is the partial class. Read on to learn more about it.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Python comes with a fun module called functools. One of its classes is the partial class. You can use it to create a new function with partial application of the arguments and keywords that you pass to it. You can use partial to "freeze" a portion of your function’s arguments and/or keywords which result in a new object. Another way to put it is that partial creates a new function with some defaults. Let’s look at an example.

>>> from functools import partial
>>> def add(x, y):
...     return x + y
... 
>>> p_add = partial(add, 2)
>>> p_add(4)
6

Here we create a simple adding function that returns the result of adding its arguments, x and y. Next, we create a new callable by creating an instance of partial and passing it to our function and an argument for that function. In other words, we are basically defaulting the x parameter of our add function to the number 2. Finally, we call our new callable, p_add, with the argument of the number 4 which results in 6 because 2 + 4 = 6.

One handy use-case for partials is to pass arguments to callbacks. Let’s take a look using wxPython:

import wx

from functools import partial 


########################################################################
class MainFrame(wx.Frame):
    """
    This app shows a group of buttons
    """

    #----------------------------------------------------------------------
    def __init__(self, *args, **kwargs):
        """Constructor"""
        super(MainFrame, self).__init__(parent=None, title='Partial')
        panel = wx.Panel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        btn_labels = ['one', 'two', 'three']
        for label in btn_labels:
            btn = wx.Button(panel, label=label)
            btn.Bind(wx.EVT_BUTTON, partial(self.onButton, label=label))
            sizer.Add(btn, 0, wx.ALL, 5)

        panel.SetSizer(sizer)
        self.Show()

    #----------------------------------------------------------------------
    def onButton(self, event, label):
        """
        Event handler called when a button is pressed
        """
        print 'You pressed: ', label


if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

Here we use partial to call the onButton event handler with an extra argument, which happens to be the button’s label. This might not seem all that useful to you, but if you do much GUI programming, you’ll see a lot of people asking how to do this sort of thing. Of course, you could also use a lambda instead for passing arguments to callbacks.

One use case that we’ve used at work was for our automated test framework. We tested a UI with Python and we wanted to be able to pass a function along to dismiss certain dialogs. Basically, you would pass a function along with the name of the dialog to dismiss, but it would need to be called at a certain point in the process to work correctly. Since I can’t show that code, here’s a really basic example of passing a partial function around:

from functools import partial

#----------------------------------------------------------------------
def add(x, y):
    """"""
    return x + y

#----------------------------------------------------------------------
def multiply(x, y):
    """"""
    return x * y

#----------------------------------------------------------------------
def run(func):
    """"""
    print func()

#----------------------------------------------------------------------
def main():
    """"""
    a1 = partial(add, 1, 2)
    m1 = partial(multiply, 5, 8)
    run(a1)
    run(m1)

if __name__ == "__main__":
    main()

Here we create a couple of partial functions in our main function. Next, we pass those partials to our run function, call it, and then print out the result of the function that was called.

Wrapping Up

At this point, you should know how to use functools partial to create your own "frozen" callables. Partials have many uses, but they’re not always obvious. I recommend that you just start experimenting with them and you might start seeing uses for your own code. Have fun!

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
python ,functools ,wxpython

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}