0

PHPで書かれたlibをpythonに書き直そうとしています。すべてのスフィンクス リクエストを処理します。init 関数で、デフォルトの検索モードと一致モードを設定しようとしていますが、少し問題が発生しました。設定ファイルからモードを取得します。

PHP では、定数を入力として使用する必要があります。

$this->sphinx->SetMatchMode(constant($this->conf['match_mode']));

これにより、構成ファイルの文字列が定数に変換され、すべてが機能します。私がこれをやろうとすると、トリッキーな部分はpythonで始まります:

self.sphinx.SetMatchMode(self.config['match_mode'])

私は得る:

AssertionError in
assert(mode in [SPH_MATCH_ALL, SPH_MATCH_ANY, SPH_MATCH_PHRASE, SPH_MATCH_BOOLEAN, SPH_MATCH_EXTENDED, SPH_MATCH_FULLSCAN, SPH_MATCH_EXTENDED2]) 

この場合、入力は整数である必要がありますが、入力は文字列であり、例外が発生するため変換できません-文字列はSPH_MATCH_ALL.

invalid literal for int() with base 10: 'SPH_MATCH_ALL'

これを試すと:

print type(self.config['match_mode']) # -- string
print type(SPH_MATCH_ALL) # -- integer
print SPH_MATCH_ALL # -- 1 
print SPH_MATCH_ANY # -- 0

したがって、私の質問は、文字列を整数またはそれが考えるものにどのように変換できるので、アサーションエラーが発生しないかということです。もちろん、if/else ステートメントを実行することもできますが、それはしたくありません。これを行うエレガントな方法はありますか?

4

3 に答える 3

3

constant()Python には、PHP関数に直接相当するものはありません。問題の定数がモジュールからインポートされた場合、最もクリーンな方法は次のようになります。

import myconstants
num = int(getattr(myconstants, self.config['match_mode']))

または、現在のモジュール内でグローバル スコープで定義されている場合は、次のようにすることができます。

X = 1
num = int(globals()['X'])

いずれにせよ、コードが処理するオブジェクトをユーザーが制御できるようにすることは、少し危険なことです。完全ではありませんeval()が、その道を少し下ったところにあります。そのため、そこに変換を含めましint()た。ユーザーが整数ではない名前でシステムを構成すると、変換は失敗するはずです。これを行うためのより堅牢な方法があるかもしれません - 私はそれに慣れていませんがconstant()、完全に書き直さなくても PHP コードに近いものです。

于 2010-08-19T16:44:52.453 に答える
1

私はスフィンクスに精通していませんが、あなたの質問に基づいて、このようなことを試してみます

DEFAULT = 0
mode = getattr(self.sphinx, self.config['match_mode'], DEFAULT)
self.sphinx.SetMatchMode(mode)

これは、sphinx モジュールが次の形式でモードを定義していると仮定しています。

SPH_MATCH_ANY = 0
SPH_MATCH_ALL = 1
# ....
于 2010-08-19T16:41:52.667 に答える
0

モード文字列を対応する整数に変換する関数を作成し、構成で呼び出すときにそれを使用します。

self.sphinx.SetMatchMode(modeToInt(self.config['match_mode']))

関数に必要な if/else 醜さは何でも隠すことができます。

于 2010-08-19T16:33:33.360 に答える