Ошибка утверждения Python, преобразование строки в int
Вопрос
Я пытаюсь переписать свою либеру, написанную в PHP в Python. Он обрабатывает все запросы Sphinx. В функции 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
Так что мой вопрос был бы, как я могу преобразовать строку в целое число или что -то в этом роде, что он думает, поэтому я не получу ошибку утверждения. Конечно, я мог бы просто сделать некоторые заявления, но я этого не хочу. Есть ли элегантный способ сделать это?
Решение
Python нет прямого эквивалента PHP constant()
функция Если рассматриваемая константа импортируется из модуля, самый чистый способ сделать это так:
import myconstants
num = int(getattr(myconstants, self.config['match_mode']))
Или, если это определено на глобальном объеме в текущем модуле, вы можете сделать это:
X = 1
num = int(globals()['X'])
В любом случае, вы делаете что -то немного рискованное, позволив пользователю управлять, что связано с вашим кодом. Это не совсем eval()
, но это немного вниз по этой дороге. Вот почему я включил int()
Преобразования там - они должны сбой, если пользователь настраивает систему с именем чего -то, что не целое число. Там может быть более надежные способы сделать это - мне это не совсем комфортно, но это где -то близко к вашему php constant()
код без полной переписывания.
Другие советы
Я не знаком с Sphinx, но на основе вашего вопроса, я бы попробовал что -то подобное
DEFAULT = 0
mode = getattr(self.sphinx, self.config['match_mode'], DEFAULT)
self.sphinx.SetMatchMode(mode)
Это предполагает, что модуль Sphinx определяет режимы в форме
SPH_MATCH_ANY = 0
SPH_MATCH_ALL = 1
# ....
Напишите функцию, которая преобразует строку режима в соответствующее целое число, затем используйте ее при вызове в конфигурации:
self.sphinx.SetMatchMode(modeToInt(self.config['match_mode']))
Вы можете убрать все, что если/иначе требуется уродство в функции.