Skip to content

Instantly share code, notes, and snippets.

@asalt
Last active March 10, 2016 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asalt/6330f790953fd4c144e9 to your computer and use it in GitHub Desktop.
Save asalt/6330f790953fd4c144e9 to your computer and use it in GitHub Desktop.
Decorator to make a specific argument an iterator
from functools import wraps
def make_iterable(argn=0, exceptions=[]):
"""Check to make sure an argument is an iterator.
Default argument is args[0]
Add exceptions that you wish to enclose in an iterator by providing an
iterator of their type.
Ironically, exceptions must be encapsulated in an iterator"""
def decorate(func):
@wraps(func)
def func_wrapper(*args, **kwargs):
"""Make a function iterable if it is not by putting it in a list.
Note also converts a string to a list with the string inside"""
maybe_iter = args[argn]
if not hasattr(maybe_iter, '__iter__') or any(isinstance(maybe_iter, x) for x in exceptions):
maybe_iter = [maybe_iter]
args = list(args)
args[argn] = maybe_iter
return func(*args, **kwargs)
return func_wrapper
return decorate
@asalt
Copy link
Author

asalt commented Mar 10, 2016

Lets you do this, ensuring that each specified argument gets packaged into a list:

@make_iterable(argn=0, exceptions=[str])
@make_iterable(argn=1, exceptions=[str])
def func(first, second):
    return '|'.join(first), '&'.join(second)

func('str1', ['str2', 'str3'])
# returns 'str1', 'str2&str3'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment