Python:使用“动态”定义新函数;加上;

Python:使用“动态”定义新函数;加上;,python,with-statement,Python,With Statement,我想转换以下代码: ... 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)

我想转换以下代码:

...
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)
这当然行不通

如果操作
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)
丢失行
(funcs):

编辑:

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

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

在这里将
一起使用是没有意义的。而是使用列表:

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

创建函数的方法只有两种:
def
lambda
。lambda是用于小功能的,因此它们可能不太适合您的情况。但是,如果确实需要,可以将两个lambda相互封装:

urls = [many urls]
links = []
funcs = [(lambda x:
            lambda:
              links.append(searchForLink(open(x))))(u)
         for u in urls]
对我来说,有点太含蓄了。

你不应该用“with”来做这件事(尽管,考虑到它是Python,你几乎肯定可以,使用一些奇怪的副作用和Python的动态性)

Python中“with”的目的是“用上下文管理器定义的方法包装块的执行。这允许封装常见的try…除了…finally使用模式以便于重用。”

我认为您把Python的“with”和/“with”混淆了,这可能在外观上相似,但实际上是不相关的

虽然,也许你更喜欢


我认为用用法为
创建一个类是不值得的:创建
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>和
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>比只编写一个helper函数要做更多的工作

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

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

您最好使用生成器来实现所需的延迟计算

def MakeLinks(urls):
    for url in urls:
        page = open(url)
        link = searchForLink(page)
        yield link

links = MakeLinks(urls)
当您需要链接时:

for link in links:
    print link

在这个循环过程中,URL将被查找,而不是一次查找所有URL(看起来您正试图避免这种情况)。

这将调用函数,他想返回函数对象。我不想使用函数
getFunc()
。这就是我喜欢人们在开始学习Python后被宠坏的原因。你必须把它写成一个单独的函数?!加油,伙计。。这只是一个例子。你当然可以做你的建议,但这不是我的问题。我投了+1票,然后虽然“等一下”并没有启动,现在我决定投+1票,但我不能。这是目前为止唯一有意义的答案。@Guy:是的。它告诉您如何以一种不包含您不想要的额外函数调用的方式重写代码。当然,它包含了。你唯一要问的是“想法”,这是个好问题。它比您的工作示例更简洁,并且没有修改未传递到函数中的变量的函数。如果有什么东西是你想要的,但这并没有做到,请在你的问题中明确说明它是什么。首先:你为什么要传递函数?是的,有这样的用例,但它们并不常见。其次,为什么不使用函数呢?函数没有问题。:)如果你迷路了(就像我一样),这个问题的答案是:使用列表理解。这太疯狂了。最好的答案是——谢谢。我想我确实理解
的作用。我希望将
def func():
粘贴在
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
中,并将
func.append(func)
粘贴在
中。但是,很明显,这不会那么容易。至少可以说,是“非统一的”。仍然,美丽得令人毛骨悚然;)我认为函数
func
每次都会被忽略。所以我只剩下最后一个了,即负责最后一个url的函数。我不会吗?+1:这真聪明@Guy:默认参数是在定义时计算的,所以绑定是正常的。
urls = [many urls]
links = []
funcs = []

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

links = MakeLinks(urls)
for link in links:
    print link