Frage

I'm attempting to use the answer to Is it possible to list all functions in a module? to list functions in a range of modules. But in my interpreter I get as follows:

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

As per usual, I assume there's some blindingly obvious reason as to why this is failing to list all functions in half the modules I try. The best I can guess is isfunction() only works for .py modules? If there is an innate problem not related to my stupidity, is there a way to rectify this matter?

It's clearly an issue with the isfunction(), as getmembers seems to work fine:

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

I understand there's a dir() which can be used, but it's not really quite as neat.

War es hilfreich?

Lösung

C-defined functions are not instances of the user-defined function type; they are defined in C instead, for which you could use inspect.isbuiltin().

The fool-proof method to list all functions in modules is to use inspect.isroutine() instead:

Return true if the object is a user-defined or built-in function or method.

Demo on the math module:

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

Note the built-in part of the string representation of each function object.

isroutine() returns true if one of inspect.isbuiltin(), inspect.isfunction(), inspect.ismethod() or inspect.ismethoddescriptor() returns True.

Andere Tipps

Did you read the documentation for isfunction (emphasis added):

Return true if the object is a Python function

So no, it doesn't work for builtin functions.

You could use inspect.isroutine for your test instead. This will still miss objects that define __call__, which may or may not be what you want. You could also use callable for your test, which also may or may not be what you want. It's not always a simple task to know what kind of objects you want to consider "functions", since there may be objects that are meant to act like functions but are not actually functions.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top