Method overloading for different argument type in python
Would something like this work?
self.map = {
S_Block : self._render_block,
S_Empty : self._render_empty,
S_Function: self._render_function
}
def render(self, s):
return self.map[type(s)](s)
Keeping a reference to a class object as a key in a dictionary and having it's value be the function object you want to call will make your code shorter and less error prone. The only place an error could occur here would be in the definition of the dictionary. Or one of your internal functions of course.
Overloaded functions in Python
EDIT For the new single dispatch generic functions in Python 3.4, see http://www.python.org/dev/peps/pep-0443/
You generally don't need to overload functions in Python. Python is dynamically typed, and supports optional arguments to functions.
def myfunction(first, second, third = None):
if third is None:
#just use first and second
else:
#use all three
myfunction(1, 2) # third will be None, so enter the 'if' clause
myfunction(3, 4, 5) # third isn't None, it's 5, so enter the 'else' clause
Function overloading in Python: Missing
As unwind noted, keyword arguments with default values can go a long way.
I'll also state that in my opinion, it goes against the spirit of Python to worry a lot about what types are passed into methods. In Python, I think it's more accepted to use duck typing -- asking what an object can do, rather than what it is.
Thus, if your method may accept a string or a tuple, you might do something like this:
def print_names(names):
"""Takes a space-delimited string or an iterable"""
try:
for name in names.split(): # string case
print name
except AttributeError:
for name in names:
print name
Then you could do either of these:
print_names("Ryan Billy")
print_names(("Ryan", "Billy"))
Although an API like that sometimes indicates a design problem.
How do you overload python class method based on Enum type
It appears you've misunderstood what typing.overload
does. It does not let you define different versions of your code that get run in different situations. Rather, it's used for type hinting, to indicate that several combinations of types are supported by a single implementation. None of the overload definitions of the function will ever be run, they only add better type hinting to the real version of the function that comes later.
Here's an example given in the documentation:
@overload
def process(response: None) -> None:
...
@overload
def process(response: int) -> tuple[int, str]:
...
@overload
def process(response: bytes) -> str:
...
def process(response):
<actual implementation>
Note that the ...
elipsis literal is something you might actually put in this code, it's not standing in for something only left out for the documentation. There's no body needed in those @overload
decorated functions, since they never run. The ...
literal seems to have emerged among type-hinting aficionados as a preferred body for function stubs, rather than pass
(which at least used to be the preferred "do nothing" body for a function).
If you actually need a decorator that will run a different version of a function depending on an argument's type, you might be able to use functools.singledispatch
. But it only dispatches on actual types, not literal values like you're wanting (e.g. specific instances of an Enum
).
The simple solution to your problem is just to write a set of if
/elif
/else
blocks to separate out the calls once you're inside the function:
def get_port_on_type(self, type: GetPortType, num: int, skip: Optional[List]):
if type == GetPortType.DIFF_1:
do_stuff_1()
elif type == GetPortType.DIFF_2:
do_stuff_2()
elif type == GetPortType.SAME_1:
do_stuff_3()
else: # type == GetPortType.SAME_2:
do_stuff_4()
Starting in Python 3.10, you can use the new match
and case
statements to do essentially the same thing as the chain of if
/elif
/else
code above, with a very slightly nicer syntax, but I'm still using 3.9 and I don't feel confident in writing an example for you that I can't test (see PEP 636 for a tutorial on the new statement types).
Related Topics
Plotting Dates on the X-Axis with Python's Matplotlib
Extending Setuptools Extension to Use Cmake in Setup.Py
How to Take a Screenshot/Image of a Website Using Python
How to Make Sure If Some HTML Elements Are Loaded for Selenium + Python
Loading .Rdata Files into Python
Which Key/Value Store Is the Most Promising/Stable
Financial Charts/Graphs in Ruby or Python
How to Exit Linux Terminal Using Python Script
How to Use Python2.7 Pip Instead of Default Pip
How to Use the Same Python Virtualenv on Both Windows and Linux
Importerror: Matplotlib Is Required for Plotting When the Default Backend "Matplotlib" Is Selected
Basic Python Hello World Program Syntax Error
Differencebetween Installing a Package Using Pip VS. Apt-Get
Authenticate from Linux to Windows SQL Server with Pyodbc
Locale Date Formatting in Python
Id' Is a Bad Variable Name in Python
Appending the Same String to a List of Strings in Python
Editing the Date Formatting of X-Axis Tick Labels in Matplotlib