我也为此苦苦挣扎——我最终编写了一系列函数来解决某些东西是否是原生的问题,以涵盖极端情况:
import importlib
import importlib.machinery
import inspect
QUALIFIER = '.'
EXTENSION_SUFFIXES = tuple(suffix.lstrip(QUALIFIER) \
for suffix \
in importlib.machinery.EXTENSION_SUFFIXES)
moduleof = lambda thing: getattr(thing, '__module__', '')
isbuiltin = lambda thing: moduleof(thing) == 'builtins'
suffix = lambda filename: QUALIFIER in filename \
and filename.rpartition(QUALIFIER)[-1] \
or ''
def isnativemodule(module):
""" isnativemodule(thing) → boolean predicate, True if `module`
is a native-compiled (“extension”) module.
Q.v. this fine StackOverflow answer on this subject:
https://stackoverflow.com/a/39304199/298171
"""
# Step one: modules only beyond this point:
if not inspect.ismodule(module):
return False
# Step two: return truly when “__loader__” is set:
if isinstance(getattr(module, '__loader__', None),
importlib.machinery.ExtensionFileLoader):
return True
# Step three: in leu of either of those indicators,
# check the module path’s file suffix:
try:
ext = suffix(inspect.getfile(module))
except TypeError as exc:
return 'is a built-in' in str(exc)
return ext in EXTENSION_SUFFIXES
def isnative(thing):
""" isnative(thing) → boolean predicate, True if `thing`
comes from a native-compiled (“extension”) module.
"""
module = moduleof(thing)
# You can have this next line return “True”,
# if that covers your use-cases, and thus get rid
# of “isinspectable(…)”, below:
if module == 'builtins':
return False
return isnativemodule(
importlib.import_module(
module))
def isinspectable(thing):
""" isinspectable(thing) → boolean predicate, True
if `thing` is inspectable, through the “inspect”
modules’ myriad functions and types.
"""
return (not isbuiltin(thing)) \
and (not isnative(thing))
…如前所述:上述isnativemodule(…)
函数的来源最初来自这个 StackOverflow 答案(它也可能对您有用)。编写的代码改编自CLU,我的实用程序抽屉库包。
…我也有解析和显示函数签名的代码,正如您对项目所做的那样,它确实利用了这些谓词函数。就像仅供参考