Поскольку вам абсолютно все равно, какой тип итерации вы получаете, вы можете попытаться получить итератор для параметра, используя iter ().Если iter () вызывает исключение TypeError, параметр не может быть повторен, поэтому вы создаете список или кортеж из одного элемента, который является повторяемым, и Боб - ваш дядя.
def doIt(foos):
try:
iter(foos)
except TypeError:
foos = [foos]
for foo in foos:
pass # do something here
Единственная проблема с этимподход, если foo является строкой.Строка является итеративной, поэтому передача одной строки, а не списка строк, приведет к перебиранию символов в строке.Если это проблема, вы можете добавить тест if для нее.В этот момент он начинает многословно использовать шаблонный код, поэтому я бы разбил его на собственную функцию.
def iterfy(iterable):
if isinstance(iterable, basestring):
iterable = [iterable]
try:
iter(iterable)
except TypeError:
iterable = [iterable]
return iterable
def doIt(foos):
for foo in iterfy(foos):
pass # do something
В отличие от некоторых из тех, кто отвечает, мне нравится это делать, поскольку он исключает одну вещь, которую может сделать вызывающая сторона.ошибаться при использовании вашего API.«Будьте консервативны в том, что вы генерируете, но либеральны в том, что вы принимаете».
Чтобы ответить на ваш первоначальный вопрос, то есть то, что вы должны назвать параметром, я бы все равно использовал «foos», даже если вы примете одинпункт, так как ваше намерение состоит в том, чтобы принять список.Если это не повторяется, то технически это 1012 * ошибка, хотя вы и исправите ее для вызывающего, поскольку, вероятно, они хотят обработать только один элемент.Кроме того, если вызывающий считает, , что он должен передать итеративный хотя бы один элемент, это, конечно, будет работать нормально и требует очень небольшого синтаксиса, так что зачем беспокоиться об исправлении их неправильного понимания?