Ошибка утверждения Python, преобразование строки в int

StackOverflow https://stackoverflow.com/questions/3523932

  •  29-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь переписать свою либеру, написанную в 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']))

Вы можете убрать все, что если/иначе требуется уродство в функции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top