检查扩展模块中是否定义了类对象

时间:2015-05-04 22:55:20

标签: python cython

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

inspect.isbuiltin为扩展模块中定义的 functions 返回True,为python中定义的函数返回False,但遗憾的是它没有相同的行为对于类 - 它为这两种类返回False

(这里更大的目标是我们有一个系统,它根据解析其__init__函数的文档字符串和签名为一组类生成一个命令行API。这个系统在cython因为inspect.getargspec在这些类上无法正常工作,所以我试图找出一个解决方法)

2 个答案:

答案 0 :(得分:0)

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

这是不是意味着你要找的答案是X?

要知道某个类是否会导致某些功能崩溃,例如当您执行inspect.getargspec(X.__init__)时,那么只需在inspect.getargspec(X.__init__)块中执行try: except

答案 1 :(得分: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(…)函数的源最初来自this StackOverflow answer(可能对您有用)。由is adapted CLU, my utility-drawer library package编写的代码。

…我也有code that parsesdisplays function signatures,在您寻求与项目一起使用时,它们确实利用了这些谓词功能。就像FYI