【问题标题】:inspect.isfunction doesn't work for all modules?inspect.isfunction 不适用于所有模块?
【发布时间】:2014-04-21 03:44:09
【问题描述】:

我正在尝试使用Is it possible to list all functions in a module? 的答案来列出一系列模块中的函数。但在我的解释器中,我得到如下信息:

Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect
>>> import math
>>> math.pow(5,4)
625.0
>>> inspect.getmembers(math, inspect.isfunction)
[]
>>> inspect.getmembers(inspect, inspect.isfunction)
[('_check_class', <function _check_class at 0x00C9F9C0>), ('_check_instance', <f
unction _check_instance at 0x00C9F978>), ('_get_user_defined_method', <function
_get_user_defined_method at 0x00C9FB70>), ('_getfullargs', <function _getfullarg
s at 0x00C6A4F8>), ('_is_type', <function _is_type at 0x00C9FA08>), ('_missing_a
rguments', <function _missing_arguments at 0x00C9F198>), ('_shadowed_dict', <fun
ction _shadowed_dict at 0x00C9FA50>)... foo, bar, etc]

>>> math
<module 'math' (built-in)>
>>> inspect
<module 'inspect' from 'E:\\Python33\\lib\\inspect.py'>

>>> import win32api
>>> inspect.getmembers(win32api, inspect.isfunction)
[]
>>> win32api
<module 'win32api' from 'E:\\Python33\\lib\\site-packages\\win32\\win32api.pyd'>

像往常一样,我认为有一些非常明显的原因可以解释为什么它没有列出我尝试的一半模块中的所有功能。我能猜到的最好的是 isfunction() 仅适用于 .py 模块?如果有与我的愚蠢无关的先天问题,有没有办法纠正这件事?

这显然是 isfunction() 的问题,因为 getmembers 似乎工作正常:

>>> import math
>>> import inspect
>>> inspect.getmembers(math)
[('__doc__', 'This module is always available.  It provides access to the\nmathe
matical functions defined by the C standard.'), ('__loader__', <class '_frozen_i
mportlib.BuiltinImporter'>), ('__name__', 'math'), ('__package__', ''), ('acos',
 <built-in function acos>), ('acosh', <built-in function acosh>), ('asin', <buil
t-in function asin>)... foo, bar, etc]

我知道有一个 dir() 可以使用,但它并不是那么整洁。

【问题讨论】:

    标签: python python-module inspect


    【解决方案1】:

    C 定义的函数不是用户定义的function 类型的实例;它们是在 C 中定义的,可以使用inspect.isbuiltin()

    列出模块中所有函数的万无一失的方法是改用inspect.isroutine()

    如果对象是用户定义的或内置的函数或方法,则返回 true。

    math 模块上的演示:

    >>> import inspect
    >>> import math
    >>> inspect.getmembers(math, inspect.isroutine)
    [('acos', <built-in function acos>), ('acosh', <built-in function acosh>), ('asin', <built-in function asin>), ('asinh', <built-in function asinh>), ('atan', <built-in function atan>), ('atan2', <built-in function atan2>), ('atanh', <built-in function atanh>), ('ceil', <built-in function ceil>), ('copysign', <built-in function copysign>), ('cos', <built-in function cos>), ('cosh', <built-in function cosh>), ('degrees', <built-in function degrees>), ('erf', <built-in function erf>), ('erfc', <built-in function erfc>), ('exp', <built-in function exp>), ('expm1', <built-in function expm1>), ('fabs', <built-in function fabs>), ('factorial', <built-in function factorial>), ('floor', <built-in function floor>), ('fmod', <built-in function fmod>), ('frexp', <built-in function frexp>), ('fsum', <built-in function fsum>), ('gamma', <built-in function gamma>), ('hypot', <built-in function hypot>), ('isinf', <built-in function isinf>), ('isnan', <built-in function isnan>), ('ldexp', <built-in function ldexp>), ('lgamma', <built-in function lgamma>), ('log', <built-in function log>), ('log10', <built-in function log10>), ('log1p', <built-in function log1p>), ('modf', <built-in function modf>), ('pow', <built-in function pow>), ('radians', <built-in function radians>), ('sin', <built-in function sin>), ('sinh', <built-in function sinh>), ('sqrt', <built-in function sqrt>), ('tan', <built-in function tan>), ('tanh', <built-in function tanh>), ('trunc', <built-in function trunc>)]
    

    注意每个函数对象的字符串表示的built-in 部分。

    如果inspect.isbuiltin()inspect.isfunction()inspect.ismethod()inspect.ismethoddescriptor() 之一返回 True,则isroutine() 返回 True。

    【讨论】:

      【解决方案2】:

      您是否阅读了the documentation for isfunction(已添加重点):

      如果对象是 Python 函数,则返回 true

      所以不,它不适用于内置函数。

      您可以改用inspect.isroutine 进行测试。这仍然会错过定义__call__ 的对象,这可能是也可能不是您想要的。您也可以使用callable 进行测试,这也可能是您想要的,也可能不是。知道您想将哪种对象视为“函数”并不总是一项简单的任务,因为可能有些对象的行为类似于函数,但实际上并不是函数。

      【讨论】:

      • 我确实阅读了文档,但我不知道 Python 函数引用了 Python 中 编写 的函数。我只是认为这是一些多余的描述。
      猜你喜欢
      • 1970-01-01
      • 2021-02-07
      • 2020-03-16
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多