在 cython 中处理默认参数
Posted
技术标签:
【中文标题】在 cython 中处理默认参数【英文标题】:Handling default parameters in cython 【发布时间】:2011-02-22 17:34:29 【问题描述】:我正在使用 cython 包装一些 c++ 代码,但我不确定用默认值处理参数的最佳方法是什么。
在我的 c++ 代码中,我有参数具有默认值的函数。我想以这样一种方式包装这些,如果没有给出参数,这些默认值就会被使用。有没有办法做到这一点?
此时,我可以看到提供选项参数的唯一方法是将它们定义为 python 代码的一部分(在下面 pycode.pyx 中的def func
声明中),但随后我不止一次定义了我不想要的默认值。
cppcode.h:
int init(const char *address=0, int port=0, int en_msg=false, int error=0);
pycode_c.pxd:
cdef extern from "cppcode.h":
int func(char *address, int port, int en_msg, int error)
pycode.pyx:
cimport pycode_c
def func(address, port, en_msg, error):
return pycode_c.func(address, port, en_msg, error)
【问题讨论】:
【参考方案1】:你可以用不同的参数声明函数("cppcode.pxd"
):
cdef extern from "cppcode.hpp":
int init(char *address, int port, bint en_msg, int error)
int init(char *address, int port, bint en_msg)
int init(char *address, int port)
int init(char *address)
int init()
"cppcode.hpp"
:
int init(const char *address=0, int port=0, bool en_msg=false, int error=0);
可用于 Cython 代码 ("pycode.pyx"
):
cimport cppcode
def init(address=None,port=None,en_msg=None,error=None):
if error is not None:
return cppcode.init(address, port, en_msg, error)
elif en_msg is not None:
return cppcode.init(address, port, en_msg)
elif port is not None:
return cppcode.init(address, port)
elif address is not None:
return cppcode.init(address)
return cppcode.init()
并在 Python 中尝试 ("test_pycode.py"
):
import pycode
pycode.init("address")
输出
address 0 false 0
Cython 还有arg=*
syntax(在*.pxd
文件中)作为可选参数:
cdef foo(x=*)
【讨论】:
这种方法的问题在于,虽然 C++ 限制您省略列表末尾的参数,但 Python 允许您使用关键字指定您喜欢的任何参数子集。这意味着在您的 pyx 代码中,仅仅因为error is not None
并不意味着 address
、port
和 en_msg
具有合理的值。
我想您可以使用可变长度参数列表 def init(*args)
定义 python 函数,然后从那里开始。那么关键字顺序不再是问题。不过,这一切似乎都有些难看。 Cython 显然对变量 args 有某种支持,但我不太理解常见问题解答中的示例:Variable Args。
@Andrew Aylett:正确。由你决定你想有多严格:添加明确的检查或只是在文档字符串中提及调用约定。例如,您可以与 UNSET
对象进行比较并获取 TypeError
以获取无效函数调用 gist.github.com/6a01dc02e35fb04cf97d#file_pycode.pyx
@amicitas: va_list
用于接受变量 args 的 C
函数;请注意示例中的 cdef
而不是 def
。以上是关于在 cython 中处理默认参数的主要内容,如果未能解决你的问题,请参考以下文章