Francois
Francois

Reputation: 934

Accept either int or tuple of ints as a python function parameter

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

Answers (3)

Cong Ma
Cong Ma

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 ints 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 ints" 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

v2v1
v2v1

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

khelwood
khelwood

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

Related Questions