Python Cython编译模块不允许访问定义的函数';模块';不可催缴
发现原始错误->Python Cython编译模块不允许访问定义的函数';模块';不可催缴,python,cython,Python,Cython,发现原始错误->来自CyBlack.CyBlack导入CyBlack然后将*numpy\u值作为输入传递。出现了一个新问题,因此为此创建了一个新职位。 我是Cython的新手,尝试将Black(Black Scholes,没有股票红利)从Python转换为Cython。在编译之后,它不允许我实际使用该函数。我相信有经验的人可以很容易地看到这一点并找出原因。我从CyBlack import CyBlack编译并导入函数并调用CyBlack(BlackPnL、Black_S、Black_Texpi
来自CyBlack.CyBlack导入CyBlack
然后将*numpy\u值作为输入传递。出现了一个新问题,因此为此创建了一个新职位。
我是Cython的新手,尝试将Black(Black Scholes,没有股票红利)从Python转换为Cython。在编译之后,它不允许我实际使用该函数。我相信有经验的人可以很容易地看到这一点并找出原因。我从CyBlack import CyBlack编译并导入函数并调用CyBlack(BlackPnL、Black_S、Black_Texpiry、Black_strike、Black_volatility、Black_IR、Black_callput)后得到的错误是TypeError:“module”对象不可调用
:下面是代码:
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
谢谢你的帮助!如果您需要测试一些东西,我可以发布python伪数据-尽管使用任何数据调用它都会暴露错误。。。有些东西向我指出了C代码中没有向Python公开的变量
在此处添加我的setup.py
,以便其他人可以构建此类型:python setup.py build\u ext--inplace
为python 3.5 64位窗口使用VS2015构建
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
函数为cpdef
'd<代码>设置.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])
这是用Python2.7完成的,整体设置可能略有不同,但希望这能帮助您获得一个最低限度的工作示例,并追溯如何正确运行。听起来像是CyBlack
模块实际上可能嵌入在CyBlack
包中。你的CyBlack
函数是cdef'ed而不是cpdef'ed,因此它不能通过任何Python导入来访问。我cpdef'd了它,仍然是同一个问题…你能发布CyBlack导入CyBlack的结果吗;打印(CyBlack.\uuuuu文件)
?这将输出导致错误的模块的路径。您的目录结构是什么(即您的模块在名为cyBlack
的目录中)?在名为cyBlack的目录中是。它导入时没有错误,只是不允许您向函数发送参数,这实际上是我第一次尝试的。。。不起作用。我猜在CyBlack模块中可能有一个名为CyBlack的子模块/函数。因此,如果您刚刚导入了CyBlack,那么您可能需要在代码中使用CyBlack.CyBlack()
,如果它实际上是一个函数的话。感谢您发布运行示例。实际上,我在你碰巧找到的同时找到了埋在地下的模块。现在唯一的问题是函数不允许处理numpy向量(有点违背了拥有内部循环的目的),因为我认为这就是在cython块中声明numpy数组类型的目的。我在传递nd
向量时也遇到了问题,我怀疑这是因为使用了Clog
和sqrt
而不是(矢量化的)numpy;不确定这是否是导致itI的原因。我在上面的代码中添加了[i]索引,该索引应允许每次将1个值传递给log
和sqrt
,但没有帮助。我想我已经把这个问题变成了另一个问题,应该接受你的答案,然后重新发布第2部分。。。