文字列をintに変換するPythonアサーションエラー
質問
私は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ステートメントをいくつかすることができたが、私はそれを望んでいない。これを行うエレガントな方法はありますか?
解決
Pythonには、PHPに直接相当するものはありません constant()
働き。問題の定数がモジュールからインポートされている場合、それを行うための最もクリーンな方法は次のようなものです。
import myconstants
num = int(getattr(myconstants, self.config['match_mode']))
または、現在のモジュール内のグローバルスコープで定義されている場合、これを行うことができます。
X = 1
num = int(globals()['X'])
いずれにせよ、あなたはあなたのコードを扱うオブジェクトをユーザーに制御することにより、少し危険なことをしています。それはまったくありません eval()
, 、しかし、それはその道を少しずつ下っています。それが私が含めた理由です int()
そこでの変換 - ユーザーが整数ではないものの名前でシステムを構成する場合、それらは失敗するはずです。これを行うためのより堅牢な方法があるかもしれません - 私はそれにあまり満足していませんが、それはあなたのPHPに近い場所です constant()
完全に書き直さずにコード。
他のヒント
私はスフィンクスに精通していませんが、あなたの質問に基づいて、私はこのようなことを試してみます
DEFAULT = 0
mode = getattr(self.sphinx, self.config['match_mode'], DEFAULT)
self.sphinx.SetMatchMode(mode)
それは、スフィンクスモジュールがフォームのモードを定義すると仮定しています
SPH_MATCH_ANY = 0
SPH_MATCH_ALL = 1
# ....
モード文字列を対応する整数に変換する関数を書き込み、構成を呼び出すときにそれを使用します。
self.sphinx.SetMatchMode(modeToInt(self.config['match_mode']))
If/else Uglinessが関数に必要であるものは何でもハイビングできます。