Positional-Only Arguments
In Python, it is sometimes desirable to restrict how arguments are passed to functions. Positional-only arguments are a way to specify that certain arguments must be passed positionally, and cannot be passed as keyword (or named) arguments.
Syntax for Positional-Only Arguments
To specify that some arguments must be passed positionally, you use the / character in the function definition. Any arguments before the / are positional-only. Arguments after the / can be either positional or keyword arguments.
Syntax:
def function_name(positional_only1, positional_only2, /, other_parameters): # Function body
Example of a Function with Positional-Only Arguments
Here’s an example of a function that uses positional-only arguments:
def calculate_area(length, width, /, unit='meters'): if unit == 'meters': area = length * width else: area = (length * width) * 10.7639 # Convert to square feet return area # Correct usage print(calculate_area(5, 3)) # Output: 15 (in square meters) print(calculate_area(5, 3, unit='feet')) # Output: 161.289 (in square feet) # Incorrect usage (positional-only arguments must be used before the `/`) print(calculate_area(length=5, width=3)) # TypeError: calculate_area() got some positional-only arguments passed as keyword arguments
In this example, length and width must be passed as positional arguments. The unit argument can be passed either by name or by position.
Reasons for Using Positional-Only Arguments
- Simplicity and Clarity: Enforcing certain arguments to be positional can simplify the function’s usage and prevent errors due to incorrect keyword arguments.
- Backward Compatibility: It allows compatibility with existing function signatures, especially when dealing with inherited or library functions.
- Performance Optimization: In some cases, using positional-only arguments can improve performance by avoiding the overhead of handling keyword arguments.
Positional-Only Arguments in Class Methods
Positional-only arguments can also be used in class methods. This ensures that some arguments must be passed positionally, even when the method is called on an instance of the class.
Example:
class Rectangle: def __init__(self, length, width, /): self.length = length self.width = width def area(self): return self.length * self.width # Correct usage rect = Rectangle(10, 5) print(rect.area()) # Output: 50 # Incorrect usage (positional-only arguments must be used before the `/`) rect = Rectangle(length=10, width=5) # TypeError: Rectangle() got some positional-only arguments passed as keyword arguments
Restrictions and Limitations
- Compatibility: Positional-only syntax is available starting from Python 3.8. Versions prior to Python 3.8 do not support this feature.
- Signature Clarity: While positional-only arguments can make some functions clearer, they can also make function signatures less intuitive, especially for functions with many parameters.
Summary
Positional-only arguments allow you to specify that some arguments of a function must be passed by position and not by name. Here are the key points:
- Syntax with /: Arguments before the / must be positional-only, while those after can be either positional or keyword.
- Usage: They are used to enforce simplicity, clarity, and sometimes for performance or compatibility reasons.
- Class Methods: Positional-only arguments can also be applied to class methods.
- Limitations: This syntax is available from Python 3.8 and can sometimes make function signatures less intuitive.