假设我有一个
Python程序运行缓慢 – 在profiliing之后我发现了瓶颈.我导入的第三方模块的一个特定功能特别慢.
对于这种特殊情况,我知道该函数是用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__.
有时候注意看起来像一个函数实际上是一个类,例如枚举,但一些第三方库可能会这样做.这意味着您还应该检查一个类是否在C中实现.这个更难,因为所有类都是类型的实例.一种方法可能是检查该类是否在其目录中有__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