在写接口的时候发现一个非常诡异的问题:
下面的代码在以.py文件执行时没有问题
# test.py
def foo(bar):
print(bar)
bar = {'bar':123}
foo(**bar)
一旦将其编译为.so文件,再执行就会报错
def foo(bar):
Type 'copyright', 'credits' or 'license' for more information
IPython 7.24.1 -- An enhanced Interactive Python. Type '?' for help.
from distutils.core import setup
In [1]: import param_test
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-be0f14611aca> in <module>
----> 1 import param_test
~/Git/test/cython_test/param_test.cpython-38-darwin.so in init param_test()
TypeError: foo() takes no keyword arguments
查了一下原来是因为参数个数为0和1时,在进行编译的时候会自动禁用关键字参数,所以导致报错说这个函数没有关键字参数。
官方文档的解释是:
大概意思就是“一切为了性能”
解决办法就是将always_allow_keywords设置为True即可
# setup.py
...
setup(
ext_modules=cythonize(
'./param_test.py',
compiler_directives={'always_allow_keywords': True}
)
)
参考:
https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives
https://github.com/cython/cython/issues/2136#issuecomment-376968421