在 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 并不意味着 addressporten_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 中处理默认参数的主要内容,如果未能解决你的问题,请参考以下文章

使用默认参数调用异步函数作为参数检查处理同步的函数?

在cython中使用参数声明函数时出错[关闭]

是否可以在 Ruby 中使用默认参数定义块?

函数参数处理

Cython“模板参数中的未知类型”错误

C 默认参数