Cython 编译模块不允许访问定义的函数 'module' not callable

Cython compiled module does not allow access to the function defined 'module' not callable

发现原始错误 -> from CyBlack.CyBlack import CyBlack 然后将 *numpy_value 作为输入传递。出现了一个新问题,因此为此创建了一个新的 post。

我是 Cython 的新手,并尝试将 Black(没有股票股息的 Black Scholes)从 Python 转换为 Cython。让它编译后,它不让我实际使用该功能。我相信有更多经验的人可以很容易地看到这一点并找出原因。我在编译和导入函数 from CyBlack import CyBlack 并调用 CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput) 后得到的错误是 TypeError: 'module' object is not callable:所以这是代码:

from numpy cimport ndarray
cimport numpy as np
cimport cython

cdef extern from "math.h":
    double exp(double)
    double sqrt(double)
    double pow(double)
    double log(double)
    double erf(double)

cdef double std_norm_cdf(double x):
    return 0.5*(1+erf(x/sqrt(2.0)))

@cython.boundscheck(False)
cdef CyBlack(ndarray[np.float64_t, ndim=1] BlackPnL, ndarray[np.float64_t, ndim=1] Black_S, ndarray[np.float64_t, ndim=1] Black_Texpiry, ndarray[np.float64_t, ndim=1] Black_strike, ndarray [np.float64_t, ndim=1] Black_volatility, ndarray[np.float64_t, ndim=1] Black_IR, ndarray[np.float64_t, ndim=1] Black_callput):

    cdef Py_ssize_t i
    cdef Py_ssize_t N = BlackPnL.shape[0]
    cdef double d1, d2


    for i in range(N):
        d1 = ((log(Black_S[i] / Black_strike[i]) + Black_Texpiry[i] * Black_volatility[i] **2 / 2)) / (Black_volatility[i] * sqrt(Black_Texpiry[i]))
        d2 = d1 - Black_volatility[i] * sqrt(Black_Texpiry[i])
        BlackPnL[i] = exp(-Black_IR[i] * Black_Texpiry[i]) * (Black_callput[i] * Black_S[i] * std_norm_cdf(Black_callput[i] * d1) - Black_callput[i] * Black_strike[i] * std_norm_cdf(Black_callput[i] * d2)) 

    return BlackPnL

在此感谢您的帮助!如果你需要测试一些东西,我可以 post python 伪造数据 - 尽管只是用任何数据调用它都会暴露错误......有些东西让我指出变量没有暴露给 Python 来自 C 代码。

在此处添加我的 setup.py,以便其他人可以构建此类型:python setup.py build_ext --inplace 使用 VS2015 为 Python 3.5 64 位构建 Windows。

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

setup(ext_modules = cythonize("CyBlack.pyx"), include_dirs =["C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//include", "C://Program Files (x86)//Windows Kits//10//Include//10.0.1.0240.0//ucrt", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64", "C://Anaconda3//Lib//site-packages//numpy//core//include", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64"])

而不是

from CyBlack import CyBlack

你为什么不做

import CyBlack

?

我设法让(类似的东西)以下列方式工作:

C:/dev/tmp/CyBlack/
                   __init__.py
                   setup.py
                   CyBlack.pyx

其中 CyBlack.pyx 与您的一样,除了 CyBlack 函数是 cpdefsetup.py 包含:

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

extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64']

setup(
    ext_modules=cythonize("CyBlack.pyx"),
    include_dirs=['.', numpy.get_include()],
    extra_compile_args=extra_compile_args
)

运行 然后:

C:\dev\tmp\CyBlack> python .\setup.py build_ext --compiler=msvc --inplace

将生成 C:/dev/tmp/CyBlack/CyBlack.pyd,然后我设法 运行 来自 Python 的代码:

>>> from sys import path
>>> path.insert(0, "C:/dev/tmp")
>>> from CyBlack.CyBlack import CyBlack
>>> CyBlack(*[np.array([1.0]) for _ in xrange(7)]) # I'm too lazy to put proper values here...
array([ 0.14087021])

这是用 Python 2.7 完成的,整体设置可能略有不同,但希望这可以帮助您获得一个最小的工作示例并追溯如何使你的 运行 正确。