从类方法返回作用域枚举时命名空间混乱

2024-10-04 11:29:15 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

        Gender GetGender() const;
}

我用boost::python这样包装它:

^{pr2}$

当我试图从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函数显式返回什么类型?在


Tags: the代码enumpublicgendermalefemaleclass
2条回答

你有没有可能在某个地方定义了另一个男性,女性?否则我看不出这是怎么编译的。 尝试添加类作用域:

enum_<Person::Gender>("Gender")
    .EXPORT_ENUM_VALUE(Person::Male)
    .EXPORT_ENUM_VALUE(Person::Female)
    .export_values();

因为我们没有产生错误的代码,所以我假设在您尝试pickle一个Person对象时会发生这种情况。在

您的问题与boost的使用没有特别的关系。它位于cPickle模块中。它在用嵌套类对对象进行pickle时出现问题。有关说明,请参阅此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()

运行它会产生以下输出:

^{pr2}$

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


现在您会遇到这种情况,因为python中没有类似于enum类型的东西,boost创建一个对象来表示它。枚举构造声明当前范围中的类。通过捕获类作用域,您最终在Person中创建了一个嵌套类,并得到了上面提到的pickle错误。在

你的问题有几种解决办法。在

最简单的方法是在Person的作用域之外声明枚举。您可能不想为代码组织公开除此之外的人员相关枚举。然后您可以在子模块中声明Person类,这样您的enum在某种程度上声明为接近您的类而不是太公共。在

你也可以看看boost's pickle support。但是我没有试过。在

第三种解决方案是使用pickle之外的其他方法来存储对象。在

相关问题 更多 >