cython之always_allow_keywords

TypeError

最近有個同事編譯一個腳本後,腳本里面調用函數的地方出現了問題。
用一個簡短的例子說明下:
py文件 a.py 內容以下:html

def fn(a):
    print a

fn(a=4)   #出現問題在這一行

編譯腳本build.sh以下:python

cython -D -2 --embed a.py 
gcc -c -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o a.o a.c
gcc -I/usr/include/python2.7 -o a a.o -lpython2.7

前面的a.py用python a.py執行是沒有問題的,可是用cython編譯成可執行文件後,執行就會出現以下錯誤:git

Traceback (most recent call last):
  File "a.py", line 4, in init a
    fn(a=4)
TypeError: fn() takes no keyword arguments

也就是在 fn(a=4)的時候出現了問題。這個報錯的意思是,這個fn不支持keyword參數,可是python是支持這種特性的。這不是衝突了?github

always_allow_keywords

我上網找了一下,也有人碰到這個問題:https://github.com/bottlepy/b...
這裏有人指出:web

This is actually an incorrect assertion, and there is a quite simply fix.

By default, Cython compiles functions with 0 or 1 arguments, as special PyCFunction METH_O or METH_NOARGS. This functions do not accept keyword arguments.

You can tell Cython to disable this optimization by changing the always_allow_keywords compiler directive to True (you can do it per function, per file or globally, check cython's documentation on how to do it).

This issue happens actually in all web frameworks who use tricks like this.

cython編譯器默認狀況下會作一下優化:對於沒有參數或只有一個參數的函數,會禁止keyword參數。app

特意去差了下cython文檔,確實如此:python2.7

always_allow_keywords (True / False)
Avoid the METH_NOARGS and METH_O when constructing functions/methods which take zero or one arguments. Has no effect on special methods and functions with more than one argument. The METH_NOARGS and METH_O signatures provide faster calling conventions but disallow the use of keywords.

在這裏只要開啓always_allow_keywords選項,就能夠解決問題。因此我在前面build.sh裏對cython 加了一個參數,效果以下:ide

cython -D -2 --directive always_allow_keywords=true --embed a.py

也就是增長了 --directive always_allow_keywords=true,也就解決了問題。函數

相關文章
相關標籤/搜索