gpt4 book ai didi

c++ - 从类方法返回作用域枚举时命名空间混淆

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:32 24 4
gpt4 key购买 nike

我在 C++ 中有以下代码:

class Person
{
public:
enum Gender {Male, Female};

Gender GetGender() const;
}

我以这种方式将它包装在 boost::python 中:

BOOST_PYTHON_MODULE(TestPython)
{
scope the_scope = class_<Person>("Person")
.def("GetGender", &Person::GetGender);

enum_<Person::Gender>("Gender")
.value(Male, Person::Male)
.value(Female, Person::Female)
.export_values();
}

当我尝试从 Python 调用 person.GetGender() 时,出现以下异常:

Can't pickle : attribute lookup **PyBF.TestPython.Gender**.It guesses the namespace of the Gender (which is actually **PyBF.TestPython.Person.Gender**) enum return type incorrectly.

如何告诉 GetGender 函数明确返回什么类型?

最佳答案

由于我们没有产生错误的代码,我假设它发生在您尝试 pickle Person 对象时。

您的问题与 boost 的使用没有具体关系。它位于 cPickle 模块中。它在使用嵌套类酸洗对象时出现问题。看这个answer寻求解释。这是一个产生错误的简单代码示例:

import cPickle

class MyOuterClass(object):
class MyInnerClass(object):
pass

def __init__(self):
self.my_inner_class = self.MyInnerClass()


def pickle_error():
print "Pickling ..."
my_outer_class = MyOuterClass()
print cPickle.dumps(my_outer_class)

if __name__ == "__main__":
pickle_error()

运行它会产生这个输出:

Pickling ...
Traceback (most recent call last):
File "pickle.py", line 18, in <module>
pickle_error()
File "pickle.py", line 15, in pickle_error
print cPickle.dumps(my_outer_class)
cPickle.PicklingError: Can't pickle <class '__main__.MyInnerClass'>:
attribute lookup __main__.MyInnerClass failed

如链接答案中所述,当 cPickle 向内部类询问其名称时,它返回 '__main__.MyInnerClass'。但是,在模块的命名空间中找不到此名称,因此会出现异常。


现在你体验到这一点是因为在 python 中没有类似于枚举类型的东西,所以 boost 创建一个对象来表示它。 enum_ 构造在当前范围内声明一个类。通过捕获类作用域,您最终会在 Person 中创建一个嵌套类,并且会出现上述 pickle 错误。

您的问题有几个解决方案。

最简单的方法是在 Person 的范围之外声明枚举。您可能不想为了代码组织而暴露一个 Person 的相关枚举。然后您可以在子模块中声明 Person 类,这样您的枚举在某种程度上被声明为接近您的类而不会太公开。

你也可以看看 boost's pickle support .不过我还没试过。

第三种解决方案可能是使用 pickle 以外的东西来存储您的对象。

关于c++ - 从类方法返回作用域枚举时命名空间混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8880011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com