Reputation: 934
I have the following function:
def port_status(self, port=(1, 2)):
for i in port:
print_status(i)
But I'd like the user to be able to also call the function with a single port number like so:
port_status(port=2)
In this specific case, it would end up as the following:
TypeError: 'int' object is not iterable
Is there some python magic I could use here?
Upvotes: 1
Views: 1532
Reputation: 11302
There's no magic, but in general you live with duck typing by trying to figure out if the input behaves in your expected way. This can be coupled with trying to preprocess them first in the way you want.
For example, you can modify your function to look like:
def port_status(self, port)
ports = validate_ports(port)
for p in ports:
# use p as individual port
where, in the function validate_ports
you can use a try
block to tentatively figure out (and possibly bridge) the desired behavior and the actual one, for a very crude example:
def validate_ports(port):
try:
portiter = iter(port)
except TypeError:
return [port]
return list(portiter)
This function always returns a list, so in the case when the input is a valid list of int
s or an int
, nothing breaks. But despite the name, the individual members can still behave badly, and you'll need to handle exceptions in the rest of the code.
In general, using isinstance
can be unwieldy with Python's duck typing, and concepts like "a sequence of int
s" isn't really enforceable in Python. It's your choice to mix some LBYL with EAFP or go purist, and the choice is quite subjective, which might as well be described as "magic".
Upvotes: 0
Reputation: 641
Your for i in port requires port to be a iterable object. So you could just pass port_status port=(2), and it would work.
Upvotes: -1
Reputation: 59112
You can check the type of port
.
def port_status(self, port=(1, 2)):
if isinstance(port, int):
port = (port,)
for i in port:
print_status(i)
Upvotes: 7