Python 断言错误,字符串转换为整数

0 投票
3 回答
1389 浏览
提问于 2025-04-16 03:02

我正在把用PHP写的库转换成Python,这个库处理所有的sphinx请求。在初始化函数中,我想设置默认的搜索和匹配模式,但遇到了一点问题。我是从一个配置文件中获取这些模式的。

在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

所以我的问题是,如何把这个字符串转换成整数,或者转换成它认为的其他类型,这样我就不会遇到断言错误。当然,我可以用一些if/else语句来处理,但我不想这样。有没有更优雅的方法来解决这个问题?

3 个回答

0

写一个函数,把模式字符串转换成对应的整数,然后在配置中调用这个函数:

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

你可以把需要的那些复杂的if/else逻辑放进这个函数里,这样代码看起来就会干净很多。

1

我对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
# ....
3

Python没有和PHP的 constant() 函数完全相同的功能。如果你要用的常量是从某个模块导入的,最简单的方法是这样:

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

如果这个常量是在当前模块的全局范围内定义的,你可以这样做:

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

无论哪种方式,让用户控制你的代码处理哪些对象都有点风险。这虽然不完全像 eval(),但也有点像。为了安全起见,我在这里加了 int() 转换,这样如果用户配置了一个不是整数的名称,就会出错。可能还有更稳妥的方法来实现这个功能——我对此不是很有把握,但这已经接近你在PHP中使用 constant() 的代码,而不需要完全重写。

撰写回答