4

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

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

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

谢谢

4

1 回答 1

3

检查它是否是一个实例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__.

请注意,有时看起来像函数的东西实际上是class, 例如,enumerate但某些 3rd 方库可能会这样做。这意味着您还应该检查一个类是否在 C 中实现。这一个更难,因为所有类都是type. 一种方法可能是检查该类中是否有 a __dict__dir如果没有,则应检查__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
于 2013-05-25T18:32:21.270 回答