2013-03-01 33 views
1

我正在向Python展示一些嵌套了enum的C++類。查看boost.orgwiki.python.org的示例文檔,我看不到如何在輸入範圍後離開範圍,以便返回到全局/模塊範圍。相反,每個後續範圍都嵌套在前一個範圍內。Boost.Python - 如何重新輸入模塊範圍?

舉個例子:

#include <boost/python.hpp> 

class Foo 
{ 
public: 
    enum Choose { eFoo, eBar }; 

    /* Default constructor with enum as required argument */ 
    Foo(Choose choice): m_choice(choice) {} 
    ~Foo() {} 

    Choose get() const { return m_choice; } 

private: 
    const Choose m_choice; 

}; 


class Bar 
{ 
}; 

BOOST_PYTHON_MODULE(foo) 
{ 
    using namespace boost::python; 
    scope global; 

    /* Define Foo class, and a scope to go with it. */ 
    scope in_Foo = class_<Foo> 
     ("Foo", init<Foo::Choose>()) 
     .def("rovalue", &Foo::get) 
     ; 

    /* Expose 'Choose' enum as Foo.Choose */ 
    enum_<Foo::Choose>("Choose") 
     .value("Foo", Foo::eFoo) 
     .value("Bar", Foo::eBar) 
     ; 

    /* How to get back to module scope?? */ 
    global; 
    scope(); 

    /* This currently is exposed as Foo.Bar, but should just be Bar */ 
    class_<Bar>("Bar", init<>()) 
     ; 
} 

我試圖改變這種global;行各種事情,但都以相同的結果:

$ g++ -fPIC -shared scope.cpp -o foo.so -lpython2.7 -I/usr/include/python2.7 -lboost_python 
$ python -c 'import foo; print "Bar" in dir(foo)' 
False 
$ python -c 'import foo; print "Bar" in dir(foo.Foo)' 
True 

編輯:

有再看看wiki.python.org,看起來在上面的例子中,正確的答案是使用scope within(global)以恢復到模塊級範圍。事實上,這適用於上述示例。然而不幸的是,我得到一個編譯錯誤,當我在實際應用中使用它..

#include <boost/python.hpp> 
using namespace boost; 
BOOST_PYTHON_MODULE(foo) 
{ 
    python::scope module_level; 
    /* .... */ 
    python::scope python::within(module_level); 
    /* ... */ 
} 

編譯錯誤:

error: invalid use of qualified-name 'boost::python::within' 

回答

5

諷刺的是,可能太聰明爲自己的好,這是可以實現的使用C++作用域。 boost::python::scope文檔指出,當對象的生命週期結束時,當前範圍將恢復到構建對象之前的狀態。

BOOST_PYTHON_MODULE(foo)    // set scope to foo 
{ 
    using namespace boost::python; 
    { 
    scope in_Foo = class_<Foo>  // define foo.Foo and set scope to foo.Foo 
     ("Foo", init<Foo::Choose>()) 
     .def("rovalue", &Foo::get) 
     ; 

    enum_<Foo::Choose>("Choose")  // define foo.Foo.Choose 
     .value("Foo", Foo::eFoo) 
     .value("Bar", Foo::eBar) 
     ; 
    }         // revert scope, setting scope to foo 

    class_<Bar>("Bar", init<>())  // define foo.Bar 
     ; 
} 

雖然scope對象可能已經在其一生通過其他方式管理的,我發現,使用C++範圍內scope對象作爲自動變量提供了一些並行到C++的命名空間。

+0

謝謝!我仍然是一個使用C++的完整初學者,所以仍然需要掌握許多這些狡猾的語言特性。儘管如此,這種方式運行良好! – 2013-03-02 10:49:50

+0

減少「具有諷刺意味,可能太聰明」,更多「這正是這個對象的意圖。」 – Barry 2015-12-18 16:48:39