假设我有以下 SWIG 接口文件
%include "std_string.i"
%module Test %{
std::string AmIABoolean(bool b)
{
return b ? "Sure" : "Yes I am";
}
%}
std::string AmIABoolean(bool b);
当从 Python 与此模块交互时,这在实际传递布尔值时效果很好。
>>> Test.AmIABoolean(False)
"Yes I am"
>>> Test.AmIABoolean(True)
'Sure'
但令我惊讶(和沮丧)SWIG 接受此特定测试函数的任何参数
>>> Test.AmIABoolean([])
"Yes I am"
>>> Test.AmIABoolean("Free beer")
'Sure'
有没有办法以 SWIG 将 C++ 匹配到 python 方法的方式强制执行更严格的类型检查?显然,这个示例不是很有意义,但是如果我有一个具有多个重载的方法并且一个接受布尔参数,这意味着 SWIG 总是适用于接受布尔值的特定重载,这是非常不可取的。
看看 SWIG 在接口文件中检查布尔类型的方式,这种行为并不奇怪
SWIGINTERN int
SWIG_AsVal_bool (PyObject *obj, bool *val)
{
int r = PyObject_IsTrue(obj);
if (r == -1)
return SWIG_ERROR;
if (val) *val = r ? true : false;
return SWIG_OK;
}
正如 Python 文档所说的 PyObject_IsTrue
如果对象 o 被认为为真,则返回 1,否则返回 0。这相当于 Python 表达式 not not o。失败时,返回-1。
在动态打字的美妙世界中,“免费啤酒”总是评估为真
>>> not not "Free beer"
True
但可以肯定的是,SWIG 必须能够区分一个为真的值和一个恰好评估为真的值。任何帮助深表感谢。