© 2025
gridranger
My Computer
Categories
Network neighborhood
Degoogling
Space Colony
Friendships in my life
Jousting in video games
Helsinki Biennial
Data & Encryption
Intro through traits
Hospital visit
Win 3.1 nostalgia
Poets of the Fall
Project done!
Video games that made me learn
Blaugust: Introduction
Blogger Takeout Viewer
Treasure of the Pirate King
Chimera Squad
About the icons
Family history
Random facts about me
Discovering the web-browser module
`partial` and `partialmethod`
`partial` and `partialmethod` - 2025-01-30

Have you ever heard of functools.partial() and functools.partialmethod()? I've only recently encountered them in a TkInter home project, although they've been around since Python 3.4.

I’m sure you're familiar with the concept of lambda functions (in short: anonymous functions that are declared on-the-fly in the middle of your code).

Well, in general a partial object is very close to a lambda function. But I find it more useful. Let's see an example of both.

Using them instead of lambda

We have a nice TkInter Button and every time we press it, we want to print "Hello World" to the console.

import tkinter as tk

root = tk.Tk()
root.title("Tkinter Button Example")

def on_button_click():
    print("Hello World")

button = tk.Button(root, text="Click Me!", command=on_button_click)  # šŸ‘ˆ
button.pack(pady=20)

root.mainloop()

Since the print function needs argument, we cannot use print as the value of the command keyword argument of the Button. An argumentless method is needed as an intermediate method.

Let's simplify it with lambda.

import tkinter as tk

root = tk.Tk()
root.title("Tkinter Button Example")

button = tk.Button(root, text="Click Me!", command=lambda: print("Button clicked!"))
button.pack(pady=20)

root.mainloop()

With partial, we can do the same.

from functools import partial
import tkinter as tk

root = tk.Tk()
root.title("Tkinter Button Example")

button = tk.Button(root, text="Click Me!", command=partial(print, "Button clicked!"))
button.pack(pady=20)

root.mainloop()

Okay, but why use partial when lambda is there without any import?

Well, partial objects seem to be slightly faster since lambda functions are different objects at each time they are executed, while partial objects stay the same "frozen" variants of existing methods.

They are also easier to read and debug then lambda expressions. At debug time, you can look inside the partial as a normal object and access the body of the underlying function, documentation, etc.

Using them as aliases

You can also use partial objects to create aliases to function or method calls with the same argument set, make your code more organized and readable.

from functools import partial

def print_my_text(title: str, body: list[str]) -> None:
    hr = partial(print, "+-----------------------------------+")
    hr()
    print(title)
    hr()
    print("\n".join(body))
    hr()

Inside class definition

The same effect can be achieved within class definitions. This is where partialmethod comes in. The sample class below will have 4 fully functional methods, but half of the lines can be saved.

from functools import partialmethod

class ToggleExample:
    state = False

    def _set_state(self, state: bool) -> None:
        self.state = state
        print("State is now:", state)

    turn_on = partialmethod(_set_state, True)
    turn_off = partialmethod(_set_state, False)
    toggle = partialmethod(_set_state, not state)

Faster to type and cleaner than defining them one by one, and runs faster and is more readable and easier to debug than lambda self: self._set_state(True).

I've also found a example with generators where partial's behavior was more predictable than that of lambda's.


Sources: šŸ”— partial šŸ”— partialmethod šŸ”— python - Differences between functools.partial and a similar lambda? - Stack Overflow