2010-08-19 11 views
0

Я пытаюсь переписать мой lib, написанный на PHP, в python. Он обрабатывает все запросы сфинкса. В функции init я пытаюсь установить режимы поиска по умолчанию и соответствия, но у меня возникла небольшая проблема. Я получаю режимы из файла конфигурации.Ошибка утверждения Python, преобразование строки в int

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

В этом случае вход должен быть целым числом, но вход является строкой, и я can not конвертировать его, потому что я получаю исключение - строка 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, но я этого не хочу. Есть ли элегантный способ сделать это?

+0

Почему бы просто не держать константы в dict и использовать это? – Daenyth

ответ

3

Python не имеет прямого эквивалента функции PHP constant(). Если константа в вопросе импортируется из модуля, чистый способ сделать это так:

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

Или, если он определен в глобальном масштабе в текущем модуле, вы можете сделать это:

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

В любом случае, вы делаете что-то немного рискованное, позволяя пользователю контролировать, с какими объектами связан ваш код. Это не совсем eval(), но это немного по дороге. Вот почему я включил конверсии int() - они должны потерпеть неудачу, если пользователь настраивает систему с именем чего-то, что не является целым числом. Могут быть более надежные способы сделать это - мне это не совсем удобно, но это где-то рядом с вашим кодом PHP constant() без полной перезаписи.

+0

Спасибо, вот и все! (часть глобалов). У пользователя нет доступа сделать это, его просто, что он будет использоваться на нескольких серверах, и не все из них имеют одинаковые конфигурации для sphinx. – realshadow

+0

Я также проверил бы это 's.startswith ('SPH_MATCH _')'. –

0

Написать функцию, которая преобразует строку режима в соответствующее целое число, а затем использовать это, когда вы звоните в конфигурации:

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

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

+0

Как я уже сказал в части ошибки утверждения, я не могу ее преобразовать, так как это повышает и исключение - неверный литерал для int() с базой 10: 'SPH_MATCH_ANY' – realshadow

+0

Извините, я понял это после того, как я опубликовал. Я переписал, надеюсь, более конструктивный ответ. –

+0

А, я просто прочитал ваше собственное редактирование с информацией о mroe. Проблема в том, что у вас есть SPH_MATCH_ALL, определенный как константа, но config возвращает строковый литерал 'SPH_MATCH_ALL'. Вы можете использовать поиск по словарю, используя строку «SPH_MATCH_ALL» в качестве ключа к требуемому целочисленному значению. Тогда вы можете написать - mode_to_int [self.config ['match_mode']] –

1

Я не знаком с сфинкса, но основанный на вас вопрос, я хотел бы попробовать что-то вроде этого

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

Это предполагает, что модуль сфинкс определяет режимы в виде

SPH_MATCH_ANY = 0 
SPH_MATCH_ALL = 1 
# .... 

 Смежные вопросы

  • Нет связанных вопросов^_^