属性错误:"模块"对象没有属性"func",仅通过C++调用
AttributeError: 'module' object has no attribute 'func' Only With C++ Invocation
我一直致力于将脚本子系统集成到现有体系结构中,并一直在使用boost.python库。
我的目标是使我创建的python环境与现有代码中预期的环境相同或尽可能接近,即保留命名空间约定等。这里的技巧是,我有两个源文件来说明一个用例,如果我独立启动解释器,但在我的环境中不起作用,这意味着我一定做错了什么。
作为免责声明,我不是一个经验丰富的python用户,所以我必须在这里使用正确的术语。
core.py
import sys
def func():
print "sys is",sys
print "call from core"
func()
main.py
import core
print "---------GLOBALS-------------"
globals_ = dict(globals())
for g in globals_:
print g
print "--------------LOCALS---------"
locals_ = dict(locals())
for l in locals_:
print l
print "call from main"
core.func()
从命令提示符调用python main.py
call from core
sys is <module 'sys' (built-in)>
---------GLOBALS-------------
core
__builtins__
__name__
__file__
__doc__
__package__
--------------LOCALS---------
core
g
__builtins__
__file__
globals_
__package__
__name__
__doc__
call from main
sys is <module 'sys' (built-in)>
我理解的步骤是:
- main调用import来导入core.py
- 核心模块已加载;核心名称空间及其提供的属性可以从main访问。在此过程中,core调用其func方法,打印绑定到
sys
的内容 - main调用绑定在模块核心下的函数
我如何打开脚本环境的示例:
void Run()
{
Py_Initialize();
if(PyErr_Occurred())
{
PyErr_Print();
}
// Install builtins in __main__
boost::python::object main_module = boost::python::import(ToplevelScope.c_str());
boost::python::object main_namespace = main_module.attr("__dict__");
boost::python::dict main_dictionary = boost::python::extract<boost::python::dict>(main_namespace);
main_dictionary["__builtins__"] = boost::python::handle<>(boost::python::borrowed(PyEval_GetBuiltins()));
// Load modules
LoadModule("core.py",GetDataForCore());
LoadModule("main.py",GetDataForMain());
}
void LoadModule(std::string name, char* data)
{
// First, see if the module already exists.
PyObject* new_module;
if( new_module = PyImport_AddModule(name.c_str()) )
{
if( PyDict_GetItemString(new_module,"__name__") )
{
return; // already loaded. no work to do.
}
}
// Initialize default namespace parameters - global, local
boost::python::dict base_dict = boost::python::dict();
base_dict["__builtins__"] = boost::python::handle<>(PyImport_AddModule("__builtin__"));
base_dict["__name__"] = name.c_str();
base_dict["__file__"] = name.c_str();
base_dict["__doc__"] = "None";
base_dict["__package__"] = name.c_str();
boost::python::exec( data,
boost::python::dict(base_dict), // make a copy of base_dict for both global & local
boost::python::dict(base_dict) );
}
结果输出:
call from core
sys is <module 'sys' (built-in)>
---------GLOBALS-------------
core
__builtins__
__name__
__file__
__doc__
__package__
--------------LOCALS---------
core
g
__builtins__
__file__
globals_
__package__
__name__
__doc__
call from main
[LOG] Framework error while loading script main.py.
Traceback (most recent call last):
File "<string>", line 17, in <module>
AttributeError: 'module' object has no attribute 'func'
看起来,即使在导入之后,main也无法访问core中的函数。
我怀疑这与我没有完全初始化核心模块有关。正在用PyRun_String、PyImport_ImportModule替换exec。。。并且它们都产生相同的结果。在这里,我创建了一个基本字典的副本,其中name设置为模块名称(在本例中为核心),并将其作为全局&本地词典。
我想我并没有完全初始化模块,我会做更多的阅读来把它放在一起。。。任何见解都将不胜感激!!
你似乎在试图重新发明轮子。boost::python::import
执行您想要执行的操作。加载一个模块,或者从sys.modules
中检索它(如果它以前已经导入)。如果你不想使用boost,那么你可以使用PyObject* PyImport_ImportModule(const char *name)
。只需确保模块在python的路径上即可。
然而,如果模块不是以文件的形式存在(比如源代码只存在于内存中),那么下面的程序将重新创建该功能(它不进行任何错误检查,您需要自己添加)。
py::object LoadModule(std::string name, const char* module_source)
{
namespace py = boost::python;
// create module name and filenames
py::object name_str(py::str(name.c_str()));
std::string file = name;
file += ".py";
py::object file_str(py::str(file.c_str()));
// get helper modules
py::object types(py::import("types"));
py::object sys(py::import("sys"));
if (py::dict(sys.attr("modules")).has_key(name_str)) {
return sys.attr("modules")[name_str];
}
// create empty module
py::object module(types.attr("ModuleType")(name_str));
// init module dict
py::dict base_dict = py::extract<py::dict>(module.attr("__dict__"));
base_dict["__builtins__"] = py::import("__builtins__");
base_dict["__name__"] = name_str;
base_dict["__file__"] = file_str;
// execute module code in module context
py::exec(module_source, base_dict, base_dict);
// add module to sys.modules
sys.attr("modules")[name] = module;
return module;
}
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- C++概念:如何使用'concept'检查模板化结构的属性?
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 通过指向指针数组的指针访问子类的属性
- MSVC是否支持C++11样式的属性而不是__declspec
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 类的C++属性似乎已重新初始化
- Qt Quick-如何仅从c++代码与qml属性交互
- 用概念检查属性的类型
- C++如何将同一类的实例作为属性
- 按多个属性排序
- 主函数参数的属性
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- C++删除未使用的类属性会导致 std::logic_error
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 使用内存地址访问结构的属性值
- C++调用具有 *this 属性的单个帮助程序函数
- C++ 在堆栈中包含多态属性的类对象存储
- C++ 命名参数习惯用语 - 未设置字符串属性
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?