python - 获取 Jupyter Notebook 中定义的对象的来源
问题描述
通常,如果要获取对象的来源,可以通过inspect
模块获取:
import inspect
inspect.getsource(MyObject)
但是,在 Jupyter 笔记本中,这不起作用:
import inspect
class Foo:
def __init__(self, info):
self.info = info
a = Foo("hi")
inspect.getsource(a)
抛出错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-048b6f0c2e9b> in <module>()
7 a = Foo("hi")
8
----> 9 inspect.getsource(a)
/usr/lib/python3.6/inspect.py in getsource(object)
963 or code object. The source code is returned as a single string. An
964 OSError is raised if the source code cannot be retrieved."""
--> 965 lines, lnum = getsourcelines(object)
966 return ''.join(lines)
967
/usr/lib/python3.6/inspect.py in getsourcelines(object)
950 raised if the source code cannot be retrieved."""
951 object = unwrap(object)
--> 952 lines, lnum = findsource(object)
953
954 if ismodule(object):
/usr/lib/python3.6/inspect.py in findsource(object)
763 is raised if the source code cannot be retrieved."""
764
--> 765 file = getsourcefile(object)
766 if file:
767 # Invalidate cache if needed.
/usr/lib/python3.6/inspect.py in getsourcefile(object)
679 Return None if no way can be identified to get the source.
680 """
--> 681 filename = getfile(object)
682 all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
683 all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
/usr/lib/python3.6/inspect.py in getfile(object)
661 return object.co_filename
662 raise TypeError('{!r} is not a module, class, method, '
--> 663 'function, traceback, frame, or code object'.format(object))
664
665 def getmodulename(path):
TypeError: <__main__.Foo object at 0x7fb9130ee518> is not a module, class, method, function, traceback, frame, or code object
如果我尝试找到Foo
(使用inspect.getsource(Foo)
)的来源,我会得到:
TypeError: <module '__main__'> is a built-in class
如何获取 Jupyter 笔记本中定义的类的来源?
解决方案
我找到了一种在 Jupyter Notebook 中获取类的源代码的“hacky 方式”。
假设在一个单元格中你有:
class MyClass:
test = 2
def __init__(self):
self.L = 5
def test(self, x):
return True
@classmethod
def forward(cls, x):
return x
然后您可以使用以下方法提取代码:
import inspect
from IPython.core.magics.code import extract_symbols
obj = MyClass
cell_code = "".join(inspect.linecache.getlines(new_getfile(obj)))
class_code = extract_symbols(cell_code, obj.__name__)[0][0]
print(class_code)
从这里new_getfile
定义:
import inspect, sys
def new_getfile(object, _old_getfile=inspect.getfile):
if not inspect.isclass(object):
return _old_getfile(object)
# Lookup by parent module (as in current inspect)
if hasattr(object, '__module__'):
object_ = sys.modules.get(object.__module__)
if hasattr(object_, '__file__'):
return object_.__file__
# If parent module is __main__, lookup by methods (NEW)
for name, member in inspect.getmembers(object):
if inspect.isfunction(member) and object.__qualname__ + '.' + member.__name__ == member.__qualname__:
return inspect.getfile(member)
else:
raise TypeError('Source for {!r} not found'.format(object))
inspect.getfile = new_getfile
推荐阅读
- ios - "error":"Bad Request","message":"必需的 int 参数 'customerId' 不存在",
- mysql - 在 MySQL 查询中的一系列联合选择后无法创建总计行
- python - 不支持的 BMP 压缩 - BMP 到 JPEG - PIL - Python
- java - 使用replace()在java中用不同的字符串替换字符串的3个相同字符
- java - 为什么我的编译文件夹有一个名为棒包路径的子文件夹
- docker - 从图像 ufomy/deepo 导入 mxnet 时 docker 非法指令(核心转储)
- java - 为什么在包含 jar 文件并设置构建路径后,我无法在 Eclipse photon 中导入 org.apache.commons.math3?
- c# - IIS 卷影复制
- php - 具有不同方案的同一站点上的不同证书主题AltName
- reactjs - react如何改变Echart条形图中Select Bar的颜色