我是 gem5 模拟器的新手。我正在阅读文档( http://www.m5sim.org/Configuration_/_Simulation_Scripts )试图了解一切是如何实现的。当他们写关于 Python 类的文章时,他们会这样说:
gem5 provides a collection of Python object classes that correspond to its C++ simulation object classes. These Python classes are defined in a Python module called "m5.objects". The Python class definitions for these objects can be found in .py files in src, typically in the same directory as their C++ definitions.
To make the Python classes visible, the configuration file must first import the class definitions from the m5 module
m5/objects目录下只有一个文件“__init__.py”。这是代码:
from __future__ import print_function
from __future__ import absolute_import
from m5.internal import params
from m5.SimObject import *
try:
modules = __loader__.modules
except NameError:
modules = { }
for module in modules.keys():
if module.startswith('m5.objects.'):
exec("from %s import *" % module)
通常我不使用Python编程,所以也许这就是问题所在,但我还没有完全理解这里发生了什么。在另一篇文章中Python's __loader__, what is it?他们谈论 loader 的含义,但我觉得我错过了一些东西。任何帮助,将不胜感激。提前致谢。
最佳答案
__loader__
考虑以下代码:
import sys
class FooImporter:
def find_module(self, module_name, package_path):
return self if module_name == 'foo' else None
def load_module(self, module_name):
print('FooImporter is working.')
sys.modules[module_name] = __import__('sys')
# This activates the importer
sys.meta_path.append(FooImporter())
# This should trigger our importer to import 'foo'
import foo
# Show what we've just got
print(foo)
这将导致输出:
FooImporter is working.
<module 'sys' (built-in)>
只要 PYTHONPATH
中没有名为 foo
的 python 模块即可。
Python Import Hook ( PEP 302 ) 允许我们自定义 import
的行为。在上面的示例中,模块 foo
被认为是由 FooImporter
找到并处理的。请注意,导入程序将创建模块 foo
作为 sys
的别名。完整的导入器(与我们见过的简化导入器不同)将负责将导入模块的 __loader__ 属性设置为导入器本身。
Gem5 的导入钩子(Hook)
回到你的问题,gem5 通过其模块化设计使用相同的机制来加载 SimObject
。您可以在 src/python/importer.py
中找到类名为 CodeImporter
的导入器类。
当模块 m5.object
被导入时,例如,
from m5.objects import Root
CodeImporter
将负责处理导入任务,其中将为导入的模块设置 __loader__
属性(在本例中为 m5.objects
)。如果您尝试在 m5/objects/__init__.py
中打印 __loader__
,您将得到如下内容:
<importer.CodeImporter object at 0x7f4f58941d60>
__loader__.modules
是一个字典,其中包含 gem5 维护的 SimObjects
,其中每个项目将通过来自 的
.addModule()
调用添加src/sim/init.cc
只要 SimObject
的 C++ 对应调用了 EmbeddedPython
的构造函数,它就会被添加到列表中,以便 gem5 初始化会记住将其添加到CodeImporter
的实例。例如,应该能够在注册 Root
对象的构建文件夹中找到一个 Root.py.cc
文件。 m5/object/__init__.py
末尾的循环只是通过此机制导入已知 SimObject
的列表。
我认为这应该足以让人们了解潜在的魔法并(希望)解决他们的好奇心。
关于python - m5/objects/__init__.py 文件 gem5 中发生了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63018861/