Using anonymous function in Python

I have code that loads a list of data from multiple URLs and then calls another function, passing in each result. Sort of...

def ShowUrls(self, url): Urls = self.Scraper.GetSubUrls(url) for Url in Urls: self.UI.addLink( Url[0], Url[1]) 

This works fine, but there is a long delay while self.Scraper.GetSubUrls works, then all UI calls are very fast. This causes the user interface to display β€œ0 URLs added” for a long time, and then terminates.

I would like to pass the self.UI.addlink method to the self.UI.addlink method self.Scraper.GetSubUrls that it can be called immediately after receiving each URL. This should cause the user interface to display the correct score immediately after receiving each URL.

Is it possible? If so, what is the correct syntax?

If I were in Javascript, I would do something like ....

 getSubUrls(url, function(x, y) {UI.addLink(x, y)}) 

and then inside getSubUrls do

 SomeParamMethod(Pram1, Param2) 

Is it possible? If so, what is the correct syntax?

+4
source share
2 answers

You can use lambda , but it is usually better to create a separate function and pass it.

 self.Scraper.GetSubUrls(url, lambda url: self.UI.addLink(url[0], url[1])) 

or

 def addLink(url): self.UI.addLink(url[0], url[1]) self.Scraper.GetSubUrls(url, addLink) 
+6
source

This suggestion is a bit more active, but if you control GetSubUrls , a more Pythonic approach might be to make it a generator that gives each URL as it gets. You can then handle each URL outside the function in a for loop. For example, I assume that GetSubUrls supposedly looks something like this:

 def GetSubUrls(self, url): urls = [] document = openUrl(url) for stuff in document: urls.append(stuff) return urls 

That is, it builds a list of URLs and returns the entire list. You can make it a generator:

 def GetSubUrls(self, url): document = openUrl(url) for stuff in document: yield stuff 

Then you can just do

 for url in self.Scraper.GetSubUrls(url): self.UI.addlink(url[0], url[1]) 

This is the same as before, but if GetSubUrls is a generator, it does not wait to collect all suburls and then return them. It just gives one at a time, and your code can also process them one at a time.

One of the advantages of this method is that you can store the generator and use it whenever you want, instead of calls made inside GetSubUrls . That is, you can do urls = GetSubUrls(url) , save this for later, and still urls = GetSubUrls(url) on-demand URLs later when they are retrieved one by one. Using a callback forces the GetSubUrls function GetSubUrls process all URLs at once. Another advantage is that you do not need to create a bunch of small callbacks with a bit of content; instead, you can write these single-line lines naturally as the body of a for loop.

Read Python generators for more information on this (for example, What does the yield keyword do in Python? ).

+4
source

Source: https://habr.com/ru/post/1446712/


All Articles