# Method to act on parameter or from iterable if not parameters are passed

The scenario is as follows. The API of my program will allow the user to perform some method on a particular element (let's say a tuple from a database). If this parameter is not passed to the function, then the "default" behavior is to look for a list of elements (from a database query, for example) and to act on all of them. Like this:

task(simple_object) # will process simple_object
task() # query the database with some previously defined query


And this is what I did (implementation in Python):

@task(query='SELECT * FROM User WHERE age < 18')
disable_user(user)


This way I can call the task_disable_account with one particular User or I can call it with no arguments and then every tuple from the SQL query will be processed. The definition of task decorator is as follows:

task_registry = []
def decorate(func):
def queried(*_args):
if not _args:
map(func, search(query)) # execute on result from SQL
return
return func(*_args) # execute on 1 passed parameter
return queried
return decorate


And this is how I use it (just an example, actual code is more complicated):

def main(): # lets assume a main() function
# I'm getting and ID from sys.argv and returning a User object
# If not passed via arguments, call function with no parameters
user = get_from_argv()
if user:
func(user)
else:
func()


The idea behind all this is:

1. The tasked method should only take care of the processing of 1 element, centralising the way we search for, and how we iterate over them.
2. Make it easy to add new task methods to our implementation, not having to repeat the boilerplate code over and over.
• You append to the task_registry… but where or how do you ever use it? – 200_success Mar 30 '16 at 19:26
• I added a small example usage. @200_success – licorna Mar 30 '16 at 20:28

Not going into the question as to whether or not this is a good idea, I can see very little wrong with the solution.

One thing I would very much like to suggest is the following.

map(func, search(query))


for result in search(query):

• In Python 3, map builds a iterable, and func(result) will only be called if the iterable is looped over. In this case, this is most definitely not what you want!
• In Python 2, map builds a list, and thus evaluates everything. Better, but an intermediate list is now going to be build and thrown away.
In general I would recommend only using map for functions that are side-effect free.
Another thing I'd like to remark is where you build the namedtuple. You do it inside the function, building a new Task class for every task you add. Please move that code outside of the function task.