Determine whether a Python function is already implemented in C extension

血红的双手。 提交于 2020-12-10 04:37:24

问题


Suppose I have a Python program that runs slow- after profiliing and I have identified the bottleneck. One particular function from a 3rd party module I imported is particularly slow.

For this particular case, I know that function is implemented in Python (Used Eclipse and it's easy to jump to the function definition). So I know that I can convert that function into Cython as a speed-up option. (If it is already implemented in C, there is no point in writing it in Cython...).

If I don't have an IDE, what would be an easy option to determine this? I know that I can go to the directory where the module is installed and infer that it is in C if the module is in .so. But is there any alternative?

Thanks


回答1:


Check whether it is an instance of types.FunctionType:

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

Probably you'd be safer to check for isinstance(X, (types.FunctionType, types.LambdaType).

C functions are instances of builtin_function_or_method:

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

You can access this type as types.BuiltinFunctionType/types.BuiltinMethodType.

Alternatively you can check whether the function has a __code__ attribute. Since C functions do not have bytecode, they can't have __code__.

Note sometimes what seems like a function is actually a class, e.g. enumerate but some 3rd party library may do the same. This means that you should also check whether a class is implemented in C or not. This one is harder since all classes are instances of type. A way may be to check whether the class has a __dict__ in its dir, and if it doesn't have you should check for __slots__.

Something like the following should be pretty accurate:

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)

Example usage:

>>> 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


来源:https://stackoverflow.com/questions/16746546/determine-whether-a-python-function-is-already-implemented-in-c-extension

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!