Question

Je suis en train de réécrire mon lib écrit en PHP en python. Il gère toutes les demandes de sphinx. Dans la fonction init, je suis en train de définir les modes de recherche par défaut et correspondance, mais j'ai couru dans un petit problème. Je reçois les modes à partir d'un fichier de configuration.

En PHP, vous devez utiliser une constante comme entrée:

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

convertit la chaîne à partir du fichier de configuration dans un ouvrage de constante et tout. La difficulté commence en python, lorsque je tente de faire ceci:

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

J'obtenir:

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]) 

Dans ce cas, l'entrée doit être un entier, mais l'entrée est une chaîne et je ne peux pas le convertir parce que je reçois une exception - la chaîne est SPH_MATCH_ALL.

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

Quand j'essaie ceci:

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

Ma question serait, comment puis-je convertir la chaîne en un entier ou tout ce qu'il pense est, donc je ne vais pas obtenir une erreur d'assertion. Bien sûr, que je pouvais faire quelques if / else, mais je ne veux pas que ça. Y at-il de façon élégante de le faire?

Était-ce utile?

La solution

Python n'a pas d'équivalent direct de la fonction constant() PHP. Si la constante en question est importé d'un module, la plus propre façon de le faire est comme ceci:

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

Ou si elle est définie à portée globale dans le module actuel, vous pouvez faire ceci:

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

De toute façon, vous faites quelque chose un peu risqué en laissant le contrôle utilisateur les objets de vos offres de code avec. Il est pas tout à fait eval(), mais il est un peu plus loin dans cette voie. Voilà pourquoi j'ai inclus les conversions int() là-bas - ils devraient échouer si l'utilisateur configure le système avec le nom de quelque chose qui est pas un entier. Il peut y avoir des moyens plus solides pour le faire -. Je ne suis pas tout à fait à l'aise avec elle, mais il est quelque part près de votre code PHP constant() sans réécriture complète

Autres conseils

Je ne suis pas au courant de sphynx, mais basé sur vous question, je voudrais essayer quelque chose comme ça

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

Cela suppose que le module définit les modes sphynx sous la forme

SPH_MATCH_ANY = 0
SPH_MATCH_ALL = 1
# ....

Ecrire une fonction qui convertit la chaîne de mode à l'entier correspondant, puis utilisez que lorsque vous appelez dans la config:

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

Vous pouvez ruche loin tout if / else laideur est nécessaire dans la fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top