2016-03-21 66 views
2

我想使用Boost.Python为具有可选参数的C++构造函数创建Python包装。我想Python包装器像这样操作:带可选参数的Boost.Python构造函数

class Foo(): 
    def __init__(self, filename, phase, stages=None, level=0): 
    """ 
    filename -- string 
    phase -- int 
    stages -- optional list of strings 
    level -- optional int 
    """ 
    if stages is None: 
     stages = [] 
    # ... 

我该如何使用Boost.Python?我不知道如何与make_constructor做到这一点,我不知道如何使用raw_function构造一个构造函数。有没有比this更好的文档?

我的具体问题是试图以两个可选参数(阶段和水平)添加这两个构造函数:

https://github.com/BVLC/caffe/blob/rc3/python/caffe/_caffe.cpp#L76-L96

+2

莫非:

net = caffe.Net('network.prototxt', weights_file='weights.caffemodel', phase=caffe.TEST, level=1, stages=['deploy']) 

上拉请求可在这里的完整代码你在构造函数def中使用[args](http://www.boost.org/doc/libs/1_55_0/libs/python/doc/v2/args.html#args-spec)类?这应该让你生成'make_constructor'所用的关键字表达式。 –

+1

有关如何使[原始构造函数](https://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_constructor)位于Python Wiki上的说明。如果在make_constructor(&Net_Init,default_call_policies(),(arg(“param_file”),arg(“phase”),arg(“stages”)= object(),arg(“level”)= 0))''中设置 –

+1

, - 阶段是对象,所以你可以处理None。 –

回答

2

感谢Dan的评论,我发现一个可行的解决方案。因为有关于如何从bp::object提取对象的一些有趣花絮,等我会复制大部分在这里

// Net constructor 
shared_ptr<Net<Dtype> > Net_Init(string param_file, int phase, 
    const int level, const bp::object& stages, 
    const bp::object& weights_file) { 
    CheckFile(param_file); 

    // Convert stages from list to vector 
    vector<string> stages_vector; 
    if (!stages.is_none()) { 
     for (int i = 0; i < len(stages); i++) { 
     stages_vector.push_back(bp::extract<string>(stages[i])); 
     } 
    } 

    // Initialize net 
    shared_ptr<Net<Dtype> > net(new Net<Dtype>(param_file, 
     static_cast<Phase>(phase), level, &stages_vector)); 

    // Load weights 
    if (!weights_file.is_none()) { 
     std::string weights_file_str = bp::extract<std::string>(weights_file); 
     CheckFile(weights_file_str); 
     net->CopyTrainedLayersFrom(weights_file_str); 
    } 

    return net; 
} 

BOOST_PYTHON_MODULE(_caffe) { 
    bp::class_<Net<Dtype>, shared_ptr<Net<Dtype> >, boost::noncopyable >("Net", 
    bp::no_init) 
    .def("__init__", bp::make_constructor(&Net_Init, 
      bp::default_call_policies(), (bp::arg("network_file"), "phase", 
      bp::arg("level")=0, bp::arg("stages")=bp::object(), 
      bp::arg("weights_file")=bp::object()))) 
} 

生成的签名是:

__init__(boost::python::api::object, std::string network_file, int phase, 
    int level=0, boost::python::api::object stages=None, 
    boost::python::api::object weights_file=None) 

而且我可以用它喜欢: https://github.com/BVLC/caffe/pull/3863