2017-09-17 27 views
4

爲什麼在下面的代碼中我無法從模塊collections中獲得Callable的定義?如何獲得模塊中類的定義?

如何獲取模塊中類的定義?謝謝。

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

回答

3

一般來說,這可以通過inspect.getsource輕鬆完成,它可以接受模塊,類,方法,函數,追蹤,框架,或者代碼對象。他們代表的源代碼當然應該用Python編寫,否則會引發錯誤。

在這種特定的情況下,你恰好是不吉利的日子,而Callable_collections_abcthe Callable.__module__ name is callections.abc定義

>>> Callable.__module__ 
'collections.abc' 

這引發getsource了,因爲它不會在_collections_abc看包含Callable的定義但代之以在collections.abc中,其僅導入來自_collections_abc的所有定義:

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

但是這並沒有讓我感到很舒服。

+0

謝謝。 'getsourceline'和'getsource'通過'obj .__ module__'找到一個對象'obj'的定義嗎?那麼他們是否需要在Python中定義obj而不是二進制代碼呢? 'getfile'也通過'obj .__ module__'找到一個對象'obj'的文件嗎? – Tim

+0

@Tim yes,'getsourceline'和'getsource'在內部都使用'getfile',如果它是一個類(通過使用'inspect.isclass'來檢查),它就會從'obj'抓取'__module__'。內置模塊(在CPython中用C實現)不能與'inspect'一起使用,所以是的,它們必須在Python中定義。 –

2

get_source(fullname) 返回指定模塊的源代碼。

所以,你應該返回整個模塊,爲Callable_collections_abc模塊中定義的,所以你的代碼應該是這樣的:

import _collections_abc 

import inspect 

print(inspect.getsource(_collections_abc)) 

,你可以看到的Callable定義的打印結果。

+1

謝謝。你的意思是'inspect.getsource'只能應用於模塊對象嗎?我看到它可以應用於函數對象來獲取函數的定義。那麼,爲什麼它不適用於'inspect.Callable'類呢? – Tim

+0

也許你提到的功能被定義爲一個模塊?不確定,但我粘貼的源文件的定義來自官方文檔。 –

相關問題