【问题标题】:Boost Python - Global and Local dictionaryBoost Python - 全局和本地字典
【发布时间】:2013-11-15 07:51:44
【问题描述】:

我正在使用 BoostPython 将 Python 嵌入到我的 C++ 项目中,但我并不了解有关 Python 的所有内容,尤其是命名空间系统。

其实我用的是这段代码:

byte_code = Py_CompileString(filedata, filename, Py_file_input);

// [...]

PyObject* res = NULL;

PyObject* main_module = PyImport_AddModule("__main__");
PyObject* global_dict = PyModule_GetDict(main_module);
PyObject* local_dict = PyDict_New();
py::object local_namespace(py::handle<>(py::borrowed(local_dict)));

// Set a user object (only for this execution)
local_namespace["user_object"] = py::ptr(&MyObject);

res = PyEval_EvalCode( byte_code, global_dict, local_dict );

Py_XDECREF(res);
Py_XDECREF(local_dict);

但是当我执行类似以下的 python 脚本时:

def testB():
    print("B")

def testA():
    testB() # NameError: global name 'testB' is not defined

testA() # Works
testB() # Works

好的,我可以使用

res = PyEval_EvalCode( byte_code, global_dict, global_dict );

而不是

res = PyEval_EvalCode( byte_code, global_dict, local_dict );

但我想从任何新函数定义中保留 global_dict(因为当我将启动一个新脚本时,我不希望可以调用来自非常旧的执行的先前函数定义!)

这是命名空间的问题,不是吗?

【问题讨论】:

    标签: python c++ boost namespaces


    【解决方案1】:

    是的,这是一个命名空间问题。您应该研究 Python 处理作用域的方式(特别是“self”关键字)。

    简而言之,类成员变量和函数都以“self”为前缀。为了指定它们是当前对象范围的成员。 “Self”与 C++ 和 C# 中的“this”关键字大致相似。

    【讨论】:

    • 感谢您的回答。我尝试了“self.testB()”,但它不起作用......(NameError:未定义全局名称'self')我想这不是python类。嗯,或者我必须删除 global_dict 中的所有内容才能清理它...
    • ...也许我找到了更好的解决方案!我使用“PyDict_Copy”来复制 global_dict。然后我发送“PyEval_EvalCode(byte_code,copy_dict,copy_dict)”的副本。在此之后,我可以删除这个副本以保留真正的 global_dict !
    • 我没想到只是添加了“自我”。去工作。请做好功课。如果您了解“self”关键字的含义和作用,这将是有意义的。尽管您的解决方案可能“有效”,但除非您了解它与其他解决方案的不同之处,否则它几乎不会更好。范围解析是一个非常基本的 Python 概念,在尝试解决它之前,您应该了解它的工作原理。不要气馁,你最初的直觉是正确的,这是一个命名空间问题。了解 Python 处理范围和命名空间的方式将比解决方法更好地解决您的问题。
    • 你说得对。事实上,这就是为什么我没有关闭这个问题并用这个解决方法来回答它。我试图找到有关范围和命名空间的信息。 (例如:docs.python.org/3.3/tutorial/… )我想我现在很好地理解了这个机制。但是,我找不到这些新信息的问题的解决方案......也许这是不可能的,因为在初始配置中,所有函数定义都在 local_dict 中注册(所以在 main的本地范围内> 范围),这是其他子范围无法访问的。 (但我不确定...... :s)
    • 嗨,你有没有找到解决这个问题的方法?我有同样的问题。我正在考虑将全局字典用作本地字典,但这样做的问题是,如果任何声明为全局的对象都将存活(例如,不会调用析构函数)直到(例如不被销毁),除非它们被覆盖。跨度>
    猜你喜欢
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多