Method and Function Overloading in Python
PyMultiFunc overloading works similarly to languages that provide overloading "out of the box".
Let’s look at a basic example:
from py_multi_func.override import overload
@overload()
def foo(a: int):
print("called func `int`")
@overload()
def foo(a: str):
print("called func `str`")
foo(5) # called func `int`
foo("str") # called func `str`Do we need to specify the type as an abstract class? Here’s a simple example with cars:
from py_multi_func.override import overload
from abc import ABC
class Car(ABC):
"""Somethink code for car class..."""
...
class BMW(Car):
"""I think it could be I8"""
...
class Tesla(Car):
"""Tesla Roa..., no Tesla X, yes, of course X"""
...
class Lada(Car):
"""I don't care which model is going to be here."""
...
@overload()
def foo(car: Car):
print("called with `Car` or children `Car`")
@overload()
def foo(car: BMW):
print("called with `BMW`")
@overload()
def foo(car: Tesla):
print("called with `Tesla`")
foo(Lada()) # called with `Car` or children `Car`
foo(BMW()) # called with `BMW`
foo(Tesla()) # called with `Tesla`You can also overload your functions based on the number of arguments:
from py_multi_func.override import overload
@overload()
def foo(a: int):
print("a = int")
@overload()
def foo(a: int, b: int):
print("a = int, b = int")
foo(5) # a = int
foo(5, 5) # a = int, b = intInstead of passing an argument directly, you can use the DEFAULT_ARG class to represent a default value.
Warning
To ensure the class and its replacement as a default argument work correctly, you must follow several rules:
- The constructor of
DEFAULT_ARGmust be given the type that corresponds to the argument with the default value. DEFAULT_ARGmust be positioned exactly where the argument has a default value — for example, you cannot do this:
from py_multi_func.override import overload
from py_multi_func.defaults_arg import DEFAULT_ARG
@overload()
def foo(a: str, b: str = "default"):
print(a, b)
# NoDefaultValueForThisArgError: The argument [a] marked as (DEFAULT_ARG) does not have a default value.
# A good error that tells you where the `DEFAULT_ARG` is passed incorrectly
foo(DEFAULT_ARG(str), "somethink") - An initialized
DEFAULT_ARGcannot be passed due to the specifics of how the decorator works. If you need to pass such a value explicitly, useFAKE_DEFAULT_ARGinstead — it is identical toDEFAULT_ARG, but it is not replaced with the default value.
from py_multi_func.override import overload
from py_multi_func.defaults_arg import DEFAULT_ARG
@overload()
def foo(a: str, b: str = "default"):
print(a, b)
foo("shprot", "oli") # shprot oli
foo("this", DEFAULT_ARG(str)) # this defaultNote
- [📄(🐍)]
override.py- Contains the main logic of the decorato - [📄(🐍)]
exception.py- Contains all exceptions that may occur when working with PyMultiFunc - [📄(🐍)]
config.py- Contains constants and other static arguments for analysis during decorator execution - [📄(🐍)]
defaults_arg.py- Contains classes (DEFAULT_ARGand others) that provide access to overriding arguments with default values - [📁]
tests- Contains tests for the decorator - └── [📁]
unittest- Unittest for decorater