4

現在、dom4j を使用して HTML から特定の情報を取得するスクリプトを作成しています。

Python/Jython にはネイティブなswitchステートメントがないため、以下のように、適切なメソッドを呼び出す一連のifステートメントを使用することにしました。

if type == 'extractTitle':
    extractTitle(dom)
if type == 'extractMetaTags':
    extractMetaTags(dom)

HTMLから抽出したい情報に応じてさらに追加し、このサイトの他の場所で見つけた辞書アプローチを採用することを考えました。以下の例:

{
    'extractTitle':    extractTitle,
    'extractMetaTags': extractMetaTags
}[type](dom)

スクリプトを実行するたびにディクショナリが作成されることはわかっていますが、同時にifステートメントを使用すると、スクリプトは正しいステートメントに到達するまですべてのステートメントをチェックする必要があります。私が本当に疑問に思っているのは、どちらがパフォーマンスが優れているか、または一般的に使用するのに適しているかということです。

更新: @Brian - 素晴らしい返信をありがとう。抽出メソッドのいずれかが複数のオブジェクトを必要とする場合、質問があります。

handle_extractTag(self, dom, anotherObject)
# Do something

これを実装するには、 handleメソッドに適切な変更をどのように加えますか? あなたが私が何を意味するか知っていることを願っています:)

乾杯

4

5 に答える 5

14

dict でタグとハンドラーを指定しないようにするには、型に一致する名前のメソッドを持つハンドラー クラスを使用するだけです。例えば

class  MyHandler(object):
    def handle_extractTitle(self, dom):
        # do something

    def handle_extractMetaTags(self, dom):
        # do something

    def handle(self, type, dom):
        func = getattr(self, 'handle_%s' % type, None)
        if func is None:
            raise Exception("No handler for type %r" % type)
        return func(dom)

使用法:

 handler = MyHandler()
 handler.handle('extractTitle', dom)

アップデート:

複数の引数がある場合は、ハンドル関数を変更してそれらの引数を取り、関数に渡すだけです。より一般的なものにしたい場合 (引数のシグネチャを変更するときにハンドラー関数とハンドル メソッドの両方を変更する必要がないようにするため)、*args および **kwargs 構文を使用して、受け取ったすべての引数を渡すことができます。 . ハンドル メソッドは次のようになります。

def handle(self, type, *args, **kwargs):
    func = getattr(self, 'handle_%s' % type, None)
    if func is None:
        raise Exception("No handler for type %r" % type)
    return func(*args, **kwargs)
于 2008-11-10T14:24:04.580 に答える
2

コードを使用して実行している関数はすべて呼び出されます。

ハンドラ = {
「extractTitle」: 抽出タイトル、
「extractMetaTags」: 抽出メタタグ
}

ハンドラ[型](dom)

元のifコードのように機能します。

于 2008-11-10T14:27:44.963 に答える
1

それは、話している if ステートメントの数によって異なります。数値が非常に小さい場合は、辞書を使用するよりも効率的です。

ただし、いつものように、コードの特定のブロックを最適化する必要があることが経験とプロファイリングによってわかるまで、コードをきれいに見せるために何でもすることを強くお勧めします。

于 2008-11-10T14:26:14.857 に答える
1

あなたの辞書の使い方はまったく正しくありません。実装では、すべてのメソッドが呼び出され、役に立たないメソッドはすべて破棄されます。通常行われるのは、次のようなものです。

switch_dict = {'extractTitle': extractTitle, 
               'extractMetaTags': extractMetaTags}
switch_dict[type](dom)

そして、アイテムの数が多い(または可変の)場合、その方法は事実であり、より拡張可能です。

于 2008-11-10T14:27:35.040 に答える
1

効率の問題はほとんど関係ありません。辞書の検索は単純なハッシュ手法で行われ、if ステートメントは一度に 1 つずつ評価する必要があります。辞書の方が速い傾向にあります。

DOM からの抽出を行うポリモーフィック オブジェクトを実際に用意することをお勧めします。

がどのように設定されるかは明らかtypeではありませんが、単純な文字列ではなく、関連するオブジェクトのファミリーであるように見えます。

class ExtractTitle( object ):
    def process( dom ):
        return something

class ExtractMetaTags( object ):
    def process( dom ):
        return something

type="extractTitle" を設定する代わりに、これを行います。

type= ExtractTitle() # or ExtractMetaTags() or ExtractWhatever()
type.process( dom )

次に、この特定の辞書または if ステートメントを構築することはありません。

于 2008-11-10T14:36:53.463 に答える