如何在模块中获取类的定义?

时间:2017-09-17 12:33:10

标签: python python-3.x

为什么我无法在以下代码中从模块Callable获得collections的定义?

如何在模块中获取类的定义?感谢。

>>> from collections import Callable
>>> inspect.getsource(Callable)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/inspect.py", line 944, in getsource
    lines, lnum = getsourcelines(object)
  File "/usr/lib/python3.5/inspect.py", line 931, in getsourcelines
    lines, lnum = findsource(object)
  File "/usr/lib/python3.5/inspect.py", line 788, in findsource
    raise OSError('could not find class definition')
OSError: could not find class definition
>>> inspect.getsourcelines(Callable)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/inspect.py", line 931, in getsourcelines
    lines, lnum = findsource(object)
  File "/usr/lib/python3.5/inspect.py", line 788, in findsource
    raise OSError('could not find class definition')
OSError: could not find class definition
>>> inspect.getmodule(Callable)
<module 'collections.abc' from '/usr/lib/python3.5/collections/abc.py'>
>>> inspect.getfile(Callable)
'/usr/lib/python3.5/collections/abc.py'
>>> inspect.getsourcefile(Callable)
'/usr/lib/python3.5/collections/abc.py'

2 个答案:

答案 0 :(得分:3)

一般来说,这很容易用inspect.getsource来完成,它接受一个模块,一个类,一个方法,一个函数,一个回溯,一个框架, 或代码对象。它们代表的源当然应该用Python编写,否则会引发错误。

在这种特定情况下,您恰好是不幸的,因为Callable the Callable.__module__ name is callections.abc_collections_abc 已定义

>>> Callable.__module__
'collections.abc'

这会抛出getsource,因为它不会查找包含_collections_abc定义的Callable,而是collections.abc只会导入_collections_abc中的所有定义1}}:

>>> print(getsource(collections.abc))
from _collections_abc import *
from _collections_abc import __all__

通常情况下,getsource在查找源代码时没有问题,例如:

>>> print(getsource(getsource))
def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    OSError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
    return ''.join(lines)

在这种特定情况下,确实如此(由于Callable.__module__返回collections.abc。)您可以将__module__替换为'_collections_abc',以便查看来源的棘手方法:

>>> Callable.__module__ = '_collections_abc'
>>> src = getsource(Callable)  
>>> print(src)
class Callable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __call__(self, *args, **kwds):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Callable:
            return _check_methods(C, "__call__")
        return NotImplemented

但这并不能让我感觉很舒服。

答案 1 :(得分:2)

<强> get_source(fullname) 返回指定模块的源代码。

所以你应该返回整个模块,因为在Callable的模块中定义了_collections_abc,所以你的代码应该是这样的:

import _collections_abc

import inspect

print(inspect.getsource(_collections_abc))

您可以在打印结果中看到Callable的定义。