Partial methods in Python, enabled by the functools.partialmethod
function, provides a way to create modified versions of existing functions. These modified versions, known as partial methods, are intentionally designed to serve as method definitions rather than being callable directly. They come in handy when customizing a function by fixing certain parameters.
functools.partialmethod in Python
In Python, functools.partialmethod
is a function within the functools module. It returns a new partial method descriptor that behaves similarly to a partial function but is meant for method definitions. The resulting object is callable and can be treated as if it were the original function.
Want to customize class methods in Python without rewriting them? The functools.partialmethod
function is your solution! Part of the functools
module, it lets you create new methods for classes with pre-set arguments, similar to functools.partial
but tailored for class methods. Let’s explore how partialmethod
works, dive into practical examples, and discover how it can streamline your code!
What is functools.partialmethod?
The functools.partialmethod
function is designed to create a new method for a class by pre-setting some arguments of an existing method. It’s like functools.partial
, but specifically for methods, ensuring proper handling of the self
parameter in class contexts. This makes it ideal for creating specialized versions of methods within a class, enhancing code reusability and clarity.
Imagine it as pre-configuring a class method with default settings, ready to be called with fewer arguments later.
Syntax: Clear and Concise
The syntax for functools.partialmethod
is simple:
from functools import partialmethod
partialmethod(func, *args, **keywords)
- func: The method (or function) to modify.
- *args: Positional arguments to pre-set.
- **keywords: Keyword arguments to pre-set.
- Returns: A new method descriptor with pre-filled arguments, suitable for use in classes.
Why Use functools.partialmethod?
The partialmethod
function is perfect for:
- Creating specialized versions of class methods without duplicating code.
- Simplifying method calls by pre-setting common arguments.
- Improving readability by reducing repetitive argument passing in class methods.
- Supporting functional programming patterns within object-oriented code.
Let’s See partialmethod in Action
Here are practical examples to show how functools.partialmethod
can make your Python classes more efficient and elegant.
Example 1: Customizing a Logging Method
Create specialized logging methods for a class with pre-set log levels.
from functools import partialmethod
class Logger:
def log(self, level, message):
return f"[{level}] {message}"
error = partialmethod(log, "ERROR")
info = partialmethod(log, "INFO")
logger = Logger()
print(logger.error("File not found"))
print(logger.info("Application started"))
Output:
[ERROR] File not found
[INFO] Application started
Example 2: Pre-setting Method Parameters
Simplify a class method that formats numbers by pre-setting the precision.
from functools import partialmethod
class NumberFormatter:
def format_number(self, number, precision):
return f"{number:.{precision}f}"
two_decimal = partialmethod(format_number, precision=2)
three_decimal = partialmethod(format_number, precision=3)
formatter = NumberFormatter()
print(formatter.two_decimal(3.14159))
print(formatter.three_decimal(3.14159))
Output:
3.14
3.142
Example 3: Customizing Notifications
Create specialized notification methods with a fixed channel (e.g., email or SMS).
from functools import partialmethod
class Notifier:
def send(self, channel, message):
return f"Sending via {channel}: {message}"
email = partialmethod(send, "Email")
sms = partialmethod(send, "SMS")
notifier = Notifier()
print(notifier.email("Meeting at 10 AM"))
print(notifier.sms("Your code is 1234"))
Output:
Sending via Email: Meeting at 10 AM
Sending via SMS: Your code is 1234
Example 4: Using Keyword Arguments
Pre-set keyword arguments for a method that calculates discounts with a fixed currency.
from functools import partialmethod
class Shop:
def calculate_discount(self, price, percentage, currency="USD"):
discount = price * (percentage / 100)
return f"Discount: {discount:.2f} {currency}"
ten_percent_usd = partialmethod(calculate_discount, percentage=10, currency="USD")
twenty_percent_eur = partialmethod(calculate_discount, percentage=20, currency="EUR")
shop = Shop()
print(shop.ten_percent_usd(100))
print(shop.twenty_percent_eur(100))
Output:
Discount: 10.00 USD
Discount: 20.00 EUR
Example 5: Combining with Instance Attributes
Use partialmethod
to create methods that leverage instance attributes, like a greeting with a fixed prefix.
from functools import partialmethod
class Greeter:
def __init__(self, prefix):
self.prefix = prefix
def greet(self, name, punctuation):
return f"{self.prefix}, {name}{punctuation}"
hello_exclaim = partialmethod(greet, punctuation="!")
hello_question = partialmethod(greet, punctuation="?")
greeter = Greeter("Hello")
print(greeter.hello_exclaim("Alice"))
print(greeter.hello_question("Bob"))
Output:
Hello, Alice!
Hello, Bob?
Example 6: Reusing Methods Across Instances
Create a method to scale values with a fixed factor, reusable across different instances.
from functools import partialmethod
class Scaler:
def scale(self, value, factor):
return value * factor
double = partialmethod(scale, factor=2)
triple = partialmethod(scale, factor=3)
scaler = Scaler()
print(scaler.double(5))
print(scaler.triple(5))
Output:
10
15
Key Takeaways
Here’s what makes functools.partialmethod
a powerful tool:
- Creates specialized class methods by pre-setting arguments, reducing code duplication.
- Handles the
self
parameter automatically, unlikefunctools.partial
. - Supports both positional and keyword arguments for flexibility.
- Enhances readability by simplifying method calls in classes.
- Perfect for creating reusable, customized methods in object-oriented programming.
Pro Tip
Use partialmethod
when you want to define multiple variations of a method in a class without cluttering it with redundant code. It’s especially useful for creating intuitive interfaces, like specialized logging or notification methods, that feel natural to use.
from functools import partialmethod
class TaskManager:
def report(self, status, task):
return f"Task '{task}' is {status}"
completed = partialmethod(report, "Completed")
failed = partialmethod(report, "Failed")
manager = TaskManager()
print(manager.completed("Backup"))
print(manager.failed("Sync"))
Output:
Task 'Backup' is Completed
Task 'Sync' is Failed
Wrapping Up
The functools.partialmethod
function is a fantastic tool for customizing class methods in Python. By pre-setting arguments, it simplifies method calls, reduces code repetition, and blends functional programming with object-oriented design. Whether you’re building specialized logging, formatting, or notification methods, partialmethod
makes your classes cleaner and more intuitive. Try it in your next Python project to elevate your code’s elegance and efficiency!
For example, if a function requires two parameters, we can create a partial function from it that takes the first parameter as an argument. Later, we can call it using the other value as the parameter, making it easier to create modified versions of existing functions.
Syntax
The signature for the partialmethod function is as follows. This function returns a new partial method descriptor that, when called, behaves like a normal function, with ‘self’ as the first positional argument, ‘args’ as in a partial function, and keyword arguments as keywords. If additional arguments are passed to the call, they will be appended to ‘args’. Similarly, if additional keyword arguments are provided, they will extend and override the existing keywords.
partial(func,/,*args,*keywords)
Python partialmethod Examples:
Example 1:
In this scenario, we set the city to “Hyderabad” during object creation. Later on, we have the flexibility to change this value by assigning any desired city name of our choice.
from functools import partialmethod
class PartialDemo:
def __init__(self):
self.city = 'Hyderabad'
# Defining method
def _city(self, type):
self.city = type
#Using partialmethod
set_mumbai = partialmethod(_city, type ='mumbai')
set_chennai = partialmethod(_city, type ='chennai')
#Object creation
obj = PartialDemo()
print(obj.city)
#Resetting city value
obj.set_chennai()
print(obj.city)
Output:
Hyderabad
chennai
Example 2:
In this instance, we are calculating the simple interest for both a savings account and a current account, each with its own distinct rate of interest.
from functools import partialmethod
class PartialDemo:
def __init__(self):
self.interest = 0
self.principal=1000
# Defining method
def _si(self, r,n):
self.interest=self.principal*r*n/100.0
#Using partialmethod
set_current = partialmethod(_si, r=3,n=3)
set_saving = partialmethod(_si, r=7,n=3)
#Object creation
obj = PartialDemo()
print(obj.interest)
#computing for current account
obj.set_current()
print("Interest on current account for principal of 1000 will be",obj.interest)
#computing for saving account
obj.set_saving()
print("Interest on current account for principal of 1000 will be",obj.interest)
Output:
0
Interest on current account for principal of 1000 will be 90.0
Interest on current account for principal of 1000 will be 210.0
Example 3:
In this scenario, we are calculating the summation of numbers in the series up to the given number ‘n’.
from functools import partialmethod
class PartialDemo:
def __init__(self):
self.sum=0
# Defining method
def _series(self, n):
for i in range(1,n+1):
self.sum=self.sum+i
#Using partialmethod
set_series=partialmethod(_series,5)
#Object creation
obj = PartialDemo()
print(obj.sum)
#computing for current account
obj.set_series()
print(obj.sum)
Output:
0
15
Conclusion:
Therefore, this method provides a descriptor that is not intended to be directly callable. Instead, it serves as a means to define new methods.
References
Happy Learning 🙂