我想转换以下代码:
...
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
进入更方便的代码:
urls = [many urls]
links = []
funcs = []
for url in urls:
<STATEMENT>(funcs):
page = open(url)
link = searchForLink(page)
links.append(link)
我希望用with
语句来做这件事。正如我评论的那样,我希望能够实现:
def __enter__():
def func():
..code in the for loop..
def __exit__():
funcs.append(func)
当然这不起作用。
如果行为searchForLink
不仅仅是一个功能而是许多功能,那么列表理解对于案例并不好。它将变成一个非常难以理解的代码。例如,即使这对列表推导也有问题:
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)
答案 0 :(得分:6)
在这里使用with
是没有意义的。而是使用列表理解:
funcs = [getFunc(url, links) for url in urls]
答案 1 :(得分:4)
有点不同寻常,但你可以让装饰器注册func并将任何循环变量绑定为默认参数:
urls = [many urls]
links = []
funcs = []
for url in urls:
@funcs.append
def func(url=url):
page = open(url)
link = searchForLink(page)
links.append(link)
答案 2 :(得分:2)
丢掉第<STATEMENT>(funcs):
行
编辑:
我的意思是:你为什么要这样做?为什么要为每个页面定义一个新功能?为什么不这样做?
urls = [many urls]
links = []
for url in urls:
page = open(url)
link = searchForLink(page)
links.append(link)
答案 3 :(得分:2)
创建函数的方法只有两种:def
和lambda
。 Lambda用于小功能,因此它们可能不适合您的情况。但是,如果你真的想要,你可以将两个lambda包含在一起:
urls = [many urls]
links = []
funcs = [(lambda x:
lambda:
links.append(searchForLink(open(x))))(u)
for u in urls]
根据我的口味,有点太偏心了。
答案 4 :(得分:1)
你不应该使用“with”来做这件事(尽管,考虑到它是Python,你几乎可以肯定,使用一些奇怪的副作用和Python的动态主义)。
Python中“with”的目的是as described in the docs,“用上下文管理器定义的方法包装块的执行。这允许常见的尝试...除了...最终的使用模式被封装以便于重复使用。“
我认为你把Python的“with”与Javascript / VisualBasic“与”混淆,这可能在美容上相似,但实际上是无关的。
答案 5 :(得分:1)
好老itertools。
from itertools import imap
links.extend(imap(searchForLink, imap(open, urls)))
虽然,也许你更喜欢functional。
from functional import *
funcs = [partial(compose(compose(links.append, searchForLink), open), url) for url in urls]
for func in funcs: func()
我认为为with
使用创建一个类是不值得的:创建__enter__
和__exit__
比创建一个帮助函数要多得多。
答案 6 :(得分:1)
您可能最好使用生成器来实现您所追求的延迟计算。
def MakeLinks(urls):
for url in urls:
page = open(url)
link = searchForLink(page)
yield link
links = MakeLinks(urls)
如果您需要链接:
for link in links:
print link
在这个循环期间会查找网址,而不是一次全部查找(看起来你似乎要避免)。