python - 判断一个 Python 函数是否已经在 C 扩展中实现

标签 python cython

假设我有一个运行缓慢的 Python 程序 - 在分析之后我已经确定了瓶颈。我导入的第 3 方模块的一个特定功能特别慢。

对于这个特殊情况,我知道该函数是用 Python 实现的(使用 Eclipse,很容易跳转到函数定义)。所以我知道我可以将该函数转换为 Cython 作为加速选项。 (如果它已经在 C 中实现,那么在 Cython 中编写它是没有意义的......)。

如果我没有 IDE,确定这一点的简单选项是什么? 我知道我可以转到安装模块的目录,如果模块在 .so 中,则推断它在 C 中。但是还有其他选择吗?

谢谢

最佳答案

检查是否是types.FunctionType的实例:

>>> import types
>>> isinstance(len, types.FunctionType)
False
>>> def mylen(): pass
... 
>>> isinstance(mylen, types.FunctionType)
True

可能您检查 isinstance(X, (types.FunctionType, types.LambdaType) 会更安全。

C 函数是 builtin_function_or_method 的实例:

>>> len.__class__
<type 'builtin_function_or_method'>
>>> np.vdot.__class__
<type 'builtin_function_or_method'>

您可以通过 types.BuiltinFunctionType/types.BuiltinMethodType 访问此类型。

或者,您可以检查该函数是否具有 __code__ 属性。由于 C 函数没有字节码,因此它们不能有 __code__

请注意,有时看起来像函数的东西实际上是一个,例如enumerate 但一些第 3 方库可能会做同样的事情。这意味着您还应该检查一个类是否用 C 实现。这一个更难,因为所有类都是 type 的实例。一种方法可能是检查该类的 dir 中是否有 __dict__,如果没有,您应该检查 __slots__

类似下面的内容应该是相当准确的:

def is_implemented_in_c(obj):
    if isinstance(obj, (types.FunctionType, types.LambdaType)):
        return False
    elif isinstance(obj, type):
        if '__dict__' in dir(obj): return False
        return not hasattr(obj, '__slots__')
    # We accept also instances of classes.
    # Return True for instances of C classes, False for python classes.
    return not isinstance(obj, types.InstanceType)

示例用法:

>>> is_implemented_in_c(enumerate)
True
>>> is_implemented_in_c(len)
True
>>> is_implemented_in_c(np.vdot)
True
>>> is_implemented_in_c(lambda x: True)
False
>>> is_implemented_in_c(object)
True
>>> class A(object):
...     __slots__ = ('a', 'b')
... 
>>> is_implemented_in_c(A)
False

关于python - 判断一个 Python 函数是否已经在 C 扩展中实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16746546/

相关文章:

python - 计算我访问某个线程的次数

python - 在获取小输出大小的同时从 Python 脚本创建可执行文件

python - 如何在 Cython 的 setup.py 中指定 Python 3 源?

python - 在 cython 中指定大于 long double 的数字

python - VS代码: Python Interpreter can't find my venv

python - 在 Python 中将 Qt 图像转换为 Open CV 中的图像

Python:在类中创建抽象静态属性

python - ValueError 无效矩阵输入类型——在 Python Cplex 中

cython - 使用 cython 为一组文件制作一个 pyd

c - 使用 cython_gsl 进行集成(加上将 numpy.array 寻址到 cython)