Cython 编译单参数函数的坑

2,205 阅读1分钟

问题描述

问题起因,某个项目通过 Cython 将代码打包后部署到测试服务器,某个函数报错:TypeError: test() tasks no keyword arguments

本地复现,准备一个简单的函数以及一个 setup.py 用于打包

├── __init__.py
├── setup.py
└── test.py

test.py

def test(uid):
    print(uid)


if __name__ == "__main__":
    test(uid=321)

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize('test.py',language_level=3,))

执行结果如下

image-20201202212914066

问题解决

突然想起来有个 PEP 提到限制参数只能为位置参数,但我函数里并没有限制,不应该出现这种情况。

随后在群里寻求帮助,有个热心的老哥给了个链接:github.com/cython/cyth…

image-20201204173128671

大致意思就是说,这是 Cython 对单参数函数的“优化”,如果想要避免这种情况,需要指定编译参数。

接下来按照 ISSUE 中提到的解决方案进行修改

# setup.py
from distutils.core import setup
from Cython.Build import cythonize


setup(
    ext_modules=cythonize(
        'test.py',
        language_level=3,
        compiler_directives={"always_allow_keywords": True}),
    )

注意看第10行,这句话用来避免Cython对单参数函数的优化。

修改完之后,再次编译运行,结果如下

image-20201202215644282

至此问题解决。

总结

你遇到的问题很可能别人也遇到过,千万不要闭门造车。在自己思考、搜索过后,仍不得其解的时候,勇敢地去问。

被帮助后不要吝啬自己的感谢,更重要的是不要忘记把这份善意传递下去:你的一句话就很可能帮别人节省一天的时间,何乐而不为呢?

参考资料

  1. github.com/cython/cyth…

  2. www.python.org/dev/peps/pe…

  3. docs.cython.org/en/latest/s…