假设我有一个 Python 程序在分析后运行缓慢,并且我已经确定了瓶颈。我导入的第三方模块的一项特定功能特别慢。
对于这个特殊情况,我知道函数是用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
Run Code Online (Sandbox Code Playgroud)
也许你检查一下会更安全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'>
Run Code Online (Sandbox Code Playgroud)
types.BuiltinFunctionType您可以通过/访问此类型types.BuiltinMethodType。
或者,您可以检查该函数是否具有__code__属性。由于 C 函数没有字节码,因此它们不能有__code__.
请注意,有时看起来像函数的实际上是一个class,例如enumerate,但某些第 3 方库可能会执行相同的操作。这意味着您还应该检查一个类是否是用 C 实现的。这一个比较难,因为所有类都是 的实例type。一种方法可能是检查该类__dict__的 中是否有 a 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)
Run Code Online (Sandbox Code Playgroud)
用法示例:
>>> 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
819 次 |
| 最近记录: |