1

给定 Python 中的类对象,我如何确定该类是否在扩展模块(例如 c、c++、cython)中定义,而不是在标准 Python 中定义?

inspect.isbuiltin返回扩展模块中定义的函数和TruepythonFalse定义的函数,但不幸的是,它对类没有相同的行为——它对False两种类都返回。

(这里更大的目标是我们有一个系统,它基于解析文档字符串和__init__函数签名为一组类生成命令行 API。这个系统对于 cythoninspect.getargspec中定义的类失败,因为在这些类,所以我试图找出解决方法)

4

2 回答 2

0

“此系统对于 cython 中定义的类失败,因为 X”

这是否意味着您要寻找的答案是 X?

要知道一个类是否会导致某些函数崩溃,比如当你这样做的时候inspect.getargspec(X.__init__),那么就inspect.getargspec(X.__init__)在一个try: except块中执行。

于 2015-05-05T10:24:24.010 回答
0

我也为此苦苦挣扎——我最终编写了一系列函数来解决某些东西是否是原生的问题,以涵盖极端情况:

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,我的实用程序抽屉库包

…我也有解析显示函数签名的代码,正如您对项目所做的那样,它确实利用了这些谓词函数。就像仅供参考

于 2020-03-31T14:35:01.243 回答