Bas*_*sic 4 python anonymous-function
我有一些代码从许多URL下载数据列表,然后调用另一个函数,传入每个结果.就像是...
def ShowUrls(self, url):
Urls = self.Scraper.GetSubUrls(url)
for Url in Urls:
self.UI.addLink(
Url[0],
Url[1])
Run Code Online (Sandbox Code Playgroud)
这很好但运行时有很长的延迟self.Scraper.GetSubUrls,然后所有的UI调用都非常迅速.这会导致UI长时间显示"0 Urls added",然后完成.
我想要的是能够将self.UI.addlink方法传递给方法,self.Scraper.GetSubUrls以便一旦检索到每个URL就可以调用它.一旦检索到每个URL,这应该使UI显示正确的计数.
这可能吗?如果是这样,那么正确的语法是什么?
如果我在Javascript中,我会做类似......
getSubUrls(url, function(x, y) {UI.addLink(x, y)})
Run Code Online (Sandbox Code Playgroud)
然后,在getSubUrls里面做
SomeParamMethod(Pram1, Param2)
Run Code Online (Sandbox Code Playgroud)
这可能吗?如果是这样,那么正确的语法是什么?
您可以使用lambda,但通常更好的做法是创建一个单独的函数并传递它.
self.Scraper.GetSubUrls(url, lambda url: self.UI.addLink(url[0], url[1]))
Run Code Online (Sandbox Code Playgroud)
要么
def addLink(url):
self.UI.addLink(url[0], url[1])
self.Scraper.GetSubUrls(url, addLink)
Run Code Online (Sandbox Code Playgroud)
这个建议有点复杂,但如果你控制GetSubUrls,一个更 Pythonic 的方法可能是使它成为一个生成器,当它被检索时产生每个 URL。然后,您可以在 for 循环中处理函数外部的每个 URL。例如,我假设GetSubUrls大概看起来像这样:
def GetSubUrls(self, url):
urls = []
document = openUrl(url)
for stuff in document:
urls.append(stuff)
return urls
Run Code Online (Sandbox Code Playgroud)
也就是说,它构建一个 URL 列表并返回整个列表。您可以将其设为生成器:
def GetSubUrls(self, url):
document = openUrl(url)
for stuff in document:
yield stuff
Run Code Online (Sandbox Code Playgroud)
然后你可以做
for url in self.Scraper.GetSubUrls(url):
self.UI.addlink(url[0], url[1])
Run Code Online (Sandbox Code Playgroud)
和之前一样,但是如果GetSubUrls是生成器,它不会等待收集所有的子网址然后返回它们。它一次只产生一个,您的代码同样可以一次处理一个。
与传递回调相比,这样做的一个优点是您可以存储生成器并随时使用它,而不是在GetSubUrls. 也就是说,您可以这样做urls = GetSubUrls(url),将其保存以备后用,并在稍后“按需”迭代 URL,届时它们将被一个一个地检索。使用回调方法强制GetSubUrls函数立即处理所有 URL。另一个优点是你不需要创建一堆内容很少的小回调;相反,您可以自然地将这些单行代码编写为 for 循环的主体。
阅读 Python 生成器以获取更多信息(例如Python 中的“yield”关键字有什么作用?)。
| 归档时间: |
|
| 查看次数: |
3835 次 |
| 最近记录: |