Pregunta

Estoy tratando de reescribir mi lib escrito en PHP en Python. Se ocupa de todas las solicitudes de esfinge. En la función init, estoy tratando de establecer modos de búsqueda por defecto y los partidos, pero me he encontrado con un pequeño problema. Consigo los modos de un archivo de configuración.

En PHP, es necesario utilizar una constante como una entrada:

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

Esto convertirá la cadena desde el archivo de configuración en una constante y todo funciona. La parte difícil comienza en pitón, cuando trato de hacer esto:

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

Puedo obtener:

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

En este caso, la entrada debe ser un número entero, pero la entrada es una cadena y no puedo convertirlo porque consigo una excepción - la cadena es SPH_MATCH_ALL.

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

Cuando intento esto:

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

Así que mi pregunta sería, ¿cómo puedo convertir la cadena en un entero o lo que piensa que es, así que no conseguirá un error de aserción. Por supuesto, que yo sólo podía hacer algunas declaraciones else if /, pero no quiero eso. ¿Hay alguna manera elegante de hacer esto?

¿Fue útil?

Solución

Python no tiene un equivalente directo de la función PHP constant(). Si la constante de que se trate ha sido importada desde un módulo, la manera más limpia de hacerlo es la siguiente:

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

O si está definida en el ámbito global dentro del módulo actual, puede hacer esto:

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

De cualquier manera, estás haciendo algo un poco arriesgado al permitir al usuario controlar qué objetos sus ofertas de código con. No es bastante eval(), pero es un poco más abajo de ese camino. Es por eso que he incluido las conversiones int() allí - que debe fallar si los configura el usuario del sistema con el nombre de algo que no es un entero. Puede haber formas más robustas de hacer esto -. No estoy muy cómodo con él, pero es un lugar cerca de su código PHP constant() sin una reescritura completa

Otros consejos

No estoy familiarizado con la esfinge, pero se basa en cuestión, me gustaría probar algo como esto

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

Eso suponiendo que el módulo de Sphinx define los modos en la forma

SPH_MATCH_ANY = 0
SPH_MATCH_ALL = 1
# ....

Escribir una función que convierte la cadena de modo que el entero correspondiente, a continuación, utilizar que cuando se llama en la configuración:

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

Puede colmena de distancia si lo / más se requiere la fealdad en la función.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top