Python 如何获取模块中类的定义?
为什么我不能在下面的代码中从模块Python 如何获取模块中类的定义?,python,python-3.x,Python,Python 3.x,为什么我不能在下面的代码中从模块集合中获取可调用的定义 如何获取模块中类的定义?谢谢 >>> from collections import Callable >>> inspect.getsource(Callable) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/inspect.
集合中获取可调用的定义
如何获取模块中类的定义?谢谢
>>> 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'
>>从集合导入可调用
>>>inspect.getsource(可调用)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python3.5/inspect.py”,第944行,在getsource中
行,lnum=getsourcelines(对象)
文件“/usr/lib/python3.5/inspect.py”,第931行,在getsourcelines中
行,lnum=findsource(对象)
文件“/usr/lib/python3.5/inspect.py”,第788行,在findsource中
raise OSError('找不到类定义')
OSError:找不到类定义
>>>inspect.getsourcelines(可调用)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python3.5/inspect.py”,第931行,在getsourcelines中
行,lnum=findsource(对象)
文件“/usr/lib/python3.5/inspect.py”,第788行,在findsource中
raise OSError('找不到类定义')
OSError:找不到类定义
>>>inspect.getmodule(可调用)
>>>inspect.getfile(可调用)
“/usr/lib/python3.5/collections/abc.py”
>>>inspect.getsourcefile(可调用)
“/usr/lib/python3.5/collections/abc.py”
获取源代码(全名)
返回指定模块的源代码
因此,您应该返回整个模块,因为在\u collections\u abc
的模块中定义了可调用的
,因此您的代码应该是:
import _collections_abc
import inspect
print(inspect.getsource(_collections_abc))
您可以在打印结果中看到可调用的定义。通常,这很容易完成,它接受一个模块、一个类、一个方法、一个函数、一个回溯、一个帧、,
或代码对象。它们所代表的源代码当然应该用Python编写,否则会出现错误
在这种特殊情况下,您恰好运气不好,因为可调用是在\u collections\u abc
中定义的:
这会使getsource
关闭,因为它不会在包含Callable
s定义的\u collections\u abc
中查找,而是在collections.abc
中查找。abc
仅从\u collections\u 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)
但是,在这种特定情况下,它确实存在(由于可调用。\uuuuu模块\uuuuu
返回集合.abc
),您可以用替换\uuuu模块\uuuuuu
,以一种巧妙的方式查看源代码:
>>> 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
但这让我感觉不太舒服。谢谢。您的意思是inspect.getsource
只能应用于模块对象吗?我看到它可以应用于函数对象来获得函数的定义。那么为什么它不适用于类inspect.Callable
?也许您提到的函数被定义为一个模块?不确定,但我粘贴的getsource的定义来自官方文档。谢谢。是否通过obj.\uu模块\uuu
查找对象的定义obj
?那么,它们是否需要用Python而不是二进制代码定义obj
?getfile
是否也通过obj.\uuu模块\uuuu
查找对象的文件obj
?@Tim是的,getsourceline
和getsource
都在内部使用getfile
从obj
抓取\uu模块
,如果这是一个类的话(哪个inspect通过使用inspect.isclass
)来确定)。内置模块(在CPython的情况下用C实现)不能与inspect
一起使用,因此必须在Python中定义它们。
>>> 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