How do I overload __init__() in Python? I'm used to C/C++ where the compiler can see the difference in data type, but since there are no data types in Python, how can I make sure the third method gets called instead of the second when I give a string as parameter instead of an int?
class Handle:
def __init__(self):
self.pid = -1
def __init__(self, pid):
self.pid = pid
def __init__(self, procname):
print(procname)
self.pid = -1 # find pid by name
In C++ you can define multiple functions/methods with the same name and different signatures. In Python, everytime you define a new function with the same name of a previously defined function, you are replacing it.
To achieve what you want, you have to use optional arguments and/or explicit checks.
Here are a few possible solutions:
class Handle:
def __init__(self, pid=-1):
if isinstance(pid, str):
self.procname = pid
self.pid = -1
else:
self.procname = None
self.pid = pid
class Handle:
# Both pid and procname may be specified at the same time.
def __init__(self, pid=-1, procname=None):
self.procname = procname
self.pid = pid
class Handle:
# Either pid or procname, not both, may be specified.
def __init__(self, pid=-1, procname=None):
if pid >= 0 and procname is not None:
raise ValueError('you can specify either pid or procname, not both')
self.procname = procname
self.pid = pid
class Handle:
def __init__(self, pid=-1):
self.pid = pid
# A separate constructor, with a different name,
# because "explicit is better than implicit" and
# "sparse is better than dense" (cit. The Zen of
# Python).
# In my opinion, this is the most Pythonic solution.
@classmethod
def from_process_name(cls, procname):
pid = get_pid(procname)
return cls(pid)
By the way, I would not recommend using -1 for "not specified". I'd rather use None.
Couldn't the PEP 443 : Single-dispatch generic functions be useful in your case ?
With something like (very basic example) :
from functools import singledispatch
class Handle:
def __init__(self, arg=None):
self.pid = init_from_arg(arg)
@singledispatch
def init_from_arg(arg):
# If None or neither an integer nor a string, return None
return None
# If the argument is an integer (ie the pid)
@init_from_arg.register(int)
def _(arg):
return arg
# If the argument provided is a string (ie the procname)
@init_from_arg.register(str)
def _(arg):
return get_pid_from_procname(arg)
Edit : Following the advice in comments, these functions could probably be made staticmethods, although I had trouble with them so I reverted to the code of my original answer (see edit history if needed)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With