Python: defining new functions on the fly using "with"

python, with-statement

Solution

A bit unconventional, but you can have a decorator register the func and bind any loop variables as default arguments:

urls = [many urls]
links = []
funcs = []

for url in urls:
    @funcs.append
    def func(url=url):
        page = open(url)
        link = searchForLink(page)
        links.append(link)

Problem

I want to convert the following code: ``` ... urls = [many urls] links = [] funcs = [] for url in urls: func = getFunc(url, links) funcs.append(func) ... def getFunc(url, links): def func(): page = open(url) link = searchForLink(page) links.append(link) return func ``` into the much more convenient code: ``` urls = [many urls] links = [] funcs = [] for url in urls: <STATEMENT>(funcs): page = open(url) link = searchForLink(page) links.append(link) ``` I was hoping to do this with the `with` statement. As I commented bellow, I was hoping to achieve: ``` def __enter__(): def func(): ..code in the for loop.. def __exit__(): funcs.append(func) ``` Of course this doesn't work. List comprehensions is not good for cases were the action `searchForLink` is not just one function but many functions. It would turn into an extremely unreadable code. For example even this would be problematic with list comprehensions: ``` for url in urls: page = open(url) link1 = searchForLink(page) link2 = searchForLink(page) actionOnLink(link1) actionOnLink(link2) .... many more of these actions... links.append(link1) ```

Original source