0

私はこれを可能な限り最もpythonicな方法で書こうとしていますが、ラムダ(およびそれらを組み合わせることができるもの)について学んでいて、いくつかの問題を抱えています。

モジュールを使用してmechanize、選択コントロールの Web サイトをスクレイピングし、各オプション値をフォームに送信して、結果のコンテンツを読み取ろうとしています (おそらく、1 つの小さなステートメントに対してやりすぎているのかもしれません)。これが私が持っているものです:

 f = "ctl00$holdSection$selSubAgentFilter" #the select box field name
 self.br.select_form(nr=0) #make the form selection in the browser instance
 #here's where the magic is done
 map( (lambda item,f=f: print(self.br.form.find_control( f ).items[ item[0] ].selected.submit().read() ) ), enumerate( self.br.find_control( f ).items ) )

だから、それを分解するために、私は次のことをしようとしています:

  1. enumerate を使用してコントロールから項目を取得し、列挙されたリストをmap関数に送信して、基本的に各リスト項目を「ウォーク」することにより、選択フィールドの各オプションを反復処理します。
  2. map実行された関数にラムダ関数を使用する
  3. 項目リスト (インデックスを取得するために列挙されたもの) をラムダ関数に送信します
  4. 渡されたアイテムの列挙インデックスを使用して、フォーム コントロール内のアイテムを選択し、それを選択します。
  5. フォームを送信する
  6. 新しいブラウザ ウィンドウの内容を読み取り、print()stdout に戻します

もちろん、この場合、selectedチェーンされたメソッドのプロパティはブール値に評価され、次のエラーが発生します。

AttributeError: 'bool' object has no attribute 'submit'

しかし、あなたは私が達成しようとしていることのアイデアを得るでしょう.できればそこから離れてください。私は、最も簡単な方法ではなく、最もpythonicな方法で問題を分岐して克服しようとしています。

何かご意見は?

4

1 に答える 1

1

最も「Pythonic」な方法は、最も読みやすい方法です。for ループが機能している場合は、マップ、フィルター、またはラムダを実行する必要はありません。

リスト内包表記、マップ、フィルターなどをいつ使用するかについての適切な経験則は、データのリストで作業している場合は、内包表記、マップ、およびフィルターを使用することです。リスト内の各項目を操作するなど、反復的なロジックを実行している場合は、for ループを実行できます。

例 1: リストから不要なデータを除外する必要があるため、理解を行います。

new_list = [item for item in list if item.has_special_property]

例 2: リスト内の各項目に対して何らかの操作を実行する必要があるため、for ループを実行します。

for item in list:
    log_important_info(item)

これらは明らかに単純化された例ですが、例 1 はデータで機能し、例 2 はコードで機能することを理解していただければ幸いです。

とにかく、for item in optionループを使用し、フォーム内の適切な要素を選択して送信します。すべてループ内で行います。あなたやあなたのコードを読んでいる他の誰にとっても、あなたがしていることは非常に明確です。

あなたが上に書いたコードは、私がプロジェクトで見つけた場合、すぐに理解するのは難しいでしょう.

Pythonic の本当の意味を理解したい場合は、PEP-8を読むことを強くお勧めします。

于 2013-09-14T06:34:25.680 に答える