2011-05-24 9 views
14

मुझे एक सदस्य फ़ंक्शन के साथ एक सी ++ क्लास मिला है जो छोटे-से-बड़े पैरामीटर ले सकता है। आइए उन पैरामीटरों को नाम दें, ए-एफ। सभी पैरामीटर में डिफ़ॉल्ट मान हैं। पायथन परियोजना के एक हिस्से के रूप में मैं काम कर रहा हूं, मैं इस वर्ग को पायथन में बेनकाब करना चाहता हूं।बूस्ट :: पायथन- स्वचालित रूप से dict -> std :: map से कनवर्ट करना संभव है?

class myClass { 
    public: 
    // Constructors - set a-f to default values. 

    void SetParameters(std::map<std::string, double> &); 
    private: 
    double a, b, c, d, e, f; 
} 

void myClass::SetParameters(std::map<std::string, double> const& params) { 
    // Code to iterate over the map, and set any found key/value pairs to their 
    // corresponding variable. i.e.- "a" --> 2.0, would set myClass::a to 2.0 
} 

आदर्श रूप में, पायथन में, मैं एक dict का उपयोग कर इसे पूरा करना चाहते हैं:

>>> A = myModule.myClass(); 
>>> A.SetParameters({'a': 2.2, 'd': 4.3, b: '9.3'}) 

इस तरह, उपयोगकर्ता मूल्यों में प्रवेश कर सकता है वर्तमान में, सदस्य समारोह कुछ इस तरह दिखता किसी भी आदेश, और उनमें से किसी भी संख्या में अधिक से अधिक सवार होने के लिए दर्ज करें। बूस्ट :: पायथन में यह कैसे पूरा किया जा सकता है इस पर कोई विचार? ऐसा लगता है कि मैं नक्शा इनपुट को बूस्ट :: पायथन ऑब्जेक्ट में बदलने और निकालने के कार्यों का उपयोग करके ऐसा कर सकता हूं। हालांकि, मुझे मेरी लाइब्रेरी के इंटरफेस को बदलने की आवश्यकता होगी (मैं std :: मैप इंटरफेस रखना पसंद करूंगा, और पाइथन संस्करण के लिए कुछ मध्यस्थ/ऑटो रूपांतरण तकनीक रखूंगा)। विचार?

उत्तर

21

मुझे लगता है कि वहाँ तरीके कि अपनी खुद की कनवर्टर लिखने की तुलना में पूरा करने के लिए आसान कर रहे हैं की एक जोड़ी है शामिल हैं। आप अपने लिए रूपांतरण करने के लिए boost :: पायथन के map_indexing_suite का उपयोग कर सकते हैं, या आप अजगर में कीवर्ड तर्क का उपयोग कर सकते हैं। मैं व्यक्तिगत रूप से कीवर्ड तर्क पसंद करता हूं, क्योंकि यह ऐसा करने के लिए "पायथनिक" तरीका है।

तो यह आपके वर्ग है (मैं नक्शे के लिए एक typedef जोड़ा):

typedef std::map<std::string, double> MyMap; 

class myClass { 
public: 
    // Constructors - set a-f to default values. 

    void SetParameters(MyMap &); 
private: 
    double a, b, c, d, e, f; 
}; 

उदाहरण का उपयोग करते हुए map_indexing_suite:

#include <boost/python/suite/indexing/map_indexing_suite.hpp> 

using boost::python; 

BOOST_PYTHON_MODULE(mymodule) 
{ 
    class_<std::map<std::string, double> >("MyMap") 
     .def(map_indexing_suite<std::map<std::wstring, double> >()); 

    class_<myClass>("myClass") 
     .def("SetParameters", &myClass::SetParameters); 
} 

उदाहरण का उपयोग करके कीवर्ड तर्क।

using namespace boost::python; 

object SetParameters(tuple args, dict kwargs) 
{ 
    myClass& self = extract<myClass&>(args[0]); 

    list keys = kwargs.keys(); 

    MyMap outMap; 
    for(int i = 0; i < len(keys); ++i) { 
     object curArg = kwargs[keys[i]]; 
     if(curArg) { 
      outMap[extract<std::string>(keys[i])] = extract<double>(kwargs[keys[i]]); 
     }    
    } 
    self.SetParameters(outMap); 

    return object(); 
} 

BOOST_PYTHON_MODULE(mymodule) 
{ 
    class_<myClass>("myClass") 
     .def("SetParameters", raw_function(&SetParameters, 1)); 
} 

यह आपके अजगर में इस तरह सामान लिखने के लिए अनुमति देता है:: यह एक raw_function आवरण उपयोग करने की आवश्यकता

A.SetParameters(a = 2.2, d = 4.3, b = 9.3) 
+0

@ एलेक्सी- कीवर्ड तर्क विधि किस चीज के लिए इष्टतम दिखती है मैं करना चाहता हूं। हालांकि, मुझे आपके द्वारा पोस्ट किए गए कोड के साथ कुछ समस्याएं आ रही हैं। ऐसा लगता है कि raw_function केवल निर्दिष्ट फ़ंक्शन को टुपल और एक इनपुट के रूप में पसंद करता है। क्या क्लास सदस्य फ़ंक्शंस के लिए एक अलग, समान निर्माण है – MarkD

+0

ओह, मुझे लगता है। मुझे लगता है कि मुझे उस रैपर वर्ग का उपयोग करके मिल गया है जो कक्षा से विरासत में आता है जिसे मैं लपेटने की कोशिश कर रहा हूं। –

+0

भी, तर्क टुपल में पहला तर्क आपकी कक्षा का संदर्भ होना चाहिए। कहां स्वयं तर्क छोड़ सकते हैं और myClass निकालें और तर्क से [0]। देखें कि क्या यह काम करता है। –

0

मैं बस बूस्ट :: पायथन के साथ अपने पैर की उंगलियों को गीला कर रहा हूं इसलिए आपके प्रश्न का पूरी तरह उत्तर नहीं दे सकता। लेकिन मुझे लगता है कि पहला रोडब्लॉक गारंटी दे रहा है कि पाई dict की चाबियाँ सभी तार हैं। पाइथन डिक्ट्स को टुपल्स पर भी लगाया जा सकता है (और मैं और प्रकार मानता हूं)।

+0

कोई भी चीज जो hashable है एक महत्वपूर्ण हो सकता है, और एक एकल शब्दकोश के विभिन्न प्रकार हो सकता है चांबियाँ। –

6

This blog post इन कन्वर्टर्स को लिखने का एक स्पष्ट स्पष्ट विवरण है।

struct SomeType_from_PyObject 
{ 
    SomeType_from_PyObject(); 
    static void* convertible(PyObject* obj_ptr); 
    static void construct(PyObject* obj_ptr, 
          converter::rvalue_from_python_stage1_data* data); 
}; 

कहाँ निर्माता Boost.Python की रजिस्ट्री करने के लिए इस कनवर्टर जोड़ने के लिए जिम्मेदार है: बुनियादी पैटर्न एक वर्ग रूप है कि परिभाषित करने के लिए है

SomeType_from_PyObject::SomeType_from_PyObject() 
{ 
    converter::registry::push_back(&convertible, 
            &construct, 
            type_id<SomeType>()); 
} 

समारोह convertible या नहीं, बूस्ट बताता है

void* SomeType_from_PyObject::convertible(PyObject* obj_ptr) 
{ 
    if (PyMapping_Check(obj_ptr)) { 
     return obj_ptr; 
    } else { 
     return NULL; 
    } 
} 

construct समारोह वास्तव में की एक वस्तु बनाता है: इस कनवर्टर निर्दिष्ट अजगर वस्तु में बदल सकते हैं रूपांतरण प्रकार:

void SomeType_from_PyObject::construct(PyObject* obj_ptr, 
             converter::rvalue_from_python_stage1_data* data) 
{ 
    typedef converter::rvalue_from_python_storage<SomeType> storage_t; 
    storage_t* the_storage = reinterpret_cast<storage_t*>(data); 
    void* memory_chunk = the_storage->storage.bytes; 
    object obj(handle<>(borrowed(obj_ptr))); 
    SomeType* output = new (memory_chunk) SomeType(); 
    // Use the contents of obj to populate output, e.g. using extract<> 
    data->convertible = memory_chunk; 
} 

और फिर अपने में अपने BOOST_PYTHON_MODULE अंदर, लाइन

SomeType_from_PyObject(); 
+0

इस महान पोस्ट रे के लिए आपका बहुत बहुत धन्यवाद। मैंने इस मार्ग को नीचे जाना शुरू कर दिया (और पाइथन/सी एपीआई के बारे में कुछ और जानने के लिए मैं जो काम कर रहा था, उसे पूरा करने की संभावना है। मुझे लगता है कि अगर मैं इसे काम कर सकता हूं तो मैं एलेक्स की कीवर्ड तर्क विधि कैसे जाऊंगा, लेकिन यह बहुत मूल्यवान सामान है। +1 – MarkD

+0

मैं सहमत हूं, जबकि कनवर्टर्स मैं मार्क की समस्या को हल करने का तरीका नहीं हूं, मैं बूस्ट :: पायथन कन्वर्टर्स पर एक अच्छी पोस्ट की सराहना करता हूं। –

संबंधित मुद्दे