Python:使用“with”动态定义新函数

4 投票
7 回答
916 浏览
提问于 2025-04-15 18:53

我想把下面的代码:

...
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)

7 个回答

2

去掉这一行 <STATEMENT>(funcs):

补充说明:

我的意思是:你为什么要这么做呢?为什么每个页面都要定义一个新函数?为什么不直接这样做呢?

urls = [many urls]
links = []
for url in urls:
    page = open(url)
    link = searchForLink(page)
    links.append(link) 
6

在这里使用 with 是没有意义的。你可以用列表推导式来代替:

funcs = [getFunc(url, links) for url in urls]
4

这个方法有点特别,但你可以使用一个装饰器来注册这个函数,并把任何循环变量作为默认参数绑定到它上面:

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

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

撰写回答