5

多数のURLからデータのリストをダウンロードし、別の関数を呼び出して各結果を渡すコードがあります。何かのようなもの...

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

これは正常に機能しますが、実行中に長い遅延が発生しself.Scraper.GetSubUrls、すべてのUI呼び出しが非常に高速に行われます。これにより、UIに「0URLが追加されました」と長時間表示されてから完了します。

私が欲しいのは、self.UI.addlinkメソッドをメソッドに渡してself.Scraper.GetSubUrls、各URLが取得されるとすぐに呼び出せるようにすることです。これにより、各URLが取得されるとすぐにUIに正しいカウントが表示されます。

これは可能ですか?もしそうなら、正しい構文は何ですか?

もし私がJavascriptを使っていたら、私は次のようなことをします。

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

次に、getSubUrls内で

SomeParamMethod(Pram1, Param2)

これは可能ですか?もしそうなら、正しい構文は何ですか?

4

2 に答える 2

7

を使用することもできますlambdaが、通常は別の関数を作成して渡すことをお勧めします。

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

また

def addLink(url):
    self.UI.addLink(url[0], url[1])

self.Scraper.GetSubUrls(url, addLink)
于 2012-11-18T00:55:53.360 に答える
6

この提案はもう少し複雑ですが、制御する場合GetSubUrlsは、よりPythonicなアプローチとして、取得時に各URLを生成するジェネレーターにすることができます。次に、forループで関数の外部の各URLを処理できます。たとえば、私はGetSubUrlsおそらく次のように漠然と見えると思います:

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

つまり、URLのリストを作成し、リスト全体を返します。あなたはそれをジェネレータにすることができます:

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

その後、あなたはただすることができます

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

これは以前と同じですGetSubUrlsが、がジェネレーターの場合、すべてのsuburlを収集してから返すのを待ちません。一度に1つずつ生成され、コードも同様に一度に1つずつ処理できます。

コールバックを渡すことに対するこれの利点の1つは、ジェネレーターを格納して、内部で呼び出しを行う代わりに、いつでも使用できることですGetSubUrls。つまり、後で使用できるようurls = GetSubUrls(url)に保存し、後で「オンデマンド」でURLを繰り返し処理して、URLを1つずつ取得することができます。コールバックアプローチを使用すると、GetSubUrls関数はすべてのURLをすぐに処理します。もう1つの利点は、コンテンツが少ない小さなコールバックを大量に作成する必要がないことです。代わりに、これらのワンライナーをforループの本体として自然に書くことができます。

これに関する詳細については、Pythonジェネレーターを読んでください(たとえば、「yield」キーワードはPythonで何をしますか?)。

于 2012-11-18T01:04:47.510 に答える