2012-01-27 14 views
5

के साथ लिपटे वर्ग की मेटाक्लास सेट करना मेरे पास Event कक्षा सी ++ में परिभाषित कक्षा है जिसे मैं बूस्ट का उपयोग करके पाइथन का खुलासा करता हूं। मेरी स्क्रिप्ट इस वर्ग से प्राप्त होने की उम्मीद है, और जब भी कोई नया बाल वर्ग परिभाषित किया जाता है तो मैं कुछ प्रारंभिक करना चाहता हूं।Boost.Python

मैं Event कक्षा के मेटाक्लास को कैसे सेट कर सकता हूं जैसे कि जब भी एक पाइथन लिपि इस कक्षा से निकलती है, तो मेटाक्लास आवश्यक प्रारंभिक कार्य कर सकता है?

मैं स्पष्ट रूप से स्क्रिप्ट में एक metaclass उपयोग करने के लिए होने से बचने के लिए करना चाहते हैं ...

class KeyboardEvent(Event): # This is what I want 
    pass 

class KeyboardEvent(Event, metaclass=EventMeta): # This is not a good solution 
    pass 

संपादित करें:समाधान का एक हिस्सा

यह वहाँ लगता है कोई रास्ता नहीं है Boost.Python के साथ मेटाक्लास सेट करने के लिए। अगली सबसे अच्छी बात यह है कि वर्ग परिभाषित होने के बाद मेटाक्लास को सुधारना और बदलना है। देशी अजगर में, the safe way बदलने के लिए एक metaclass यह करने के लिए है:

B = MetaClass(B.__name__, B.__bases__, B.__dict__) 

बूस्ट में, यह कुछ इस तरह दिखाई चाहते हैं:

BOOST_PYTHON_MODULE(event) 
{ 
    using namespace boost::python; 
    using boost::python::objects::add_to_namespace; 

    class_<EventMetaClass> eventmeta("__EventMetaClass") 
     ...; 

    class_<Event> event("Event") 
     ...; 

    add_to_namespace(scope(), "Event", 
     eventmeta(event["__name__"], event["__bases__"], event["__dict__"])); 
} 

समस्या यह है कि मुझे लगता है नहीं कर पा रहे Boost.Python के साथ मेटाक्लास को परिभाषित करने का एक तरीका, यही कारण है कि मैंने How to define a Python metaclass with Boost.Python? खोला है।

इसे और अधिक किया जा सकता है -

+0

शायद 'क्लास इवेंटविथमैटा (इवेंट, मेटाक्लास = इवेंटमैटा): पास' फिर क्लास कीबोर्डइवेंट (इवेंटविथमेटा); क्लास एदरवेन्ट (इवेंटविथमेटा) '? – reclosedev

+0

@reclosedev नहीं। समस्या यह है कि मैं "मेटाक्लास" शब्द टाइप नहीं कर रहा हूं। यह है कि मेटाक्लास की आवश्यकता एक कार्यान्वयन विवरण है जो स्क्रिप्ट के संपर्क में आने वाले इंटरफ़ेस को रिसाव नहीं करना चाहिए। –

+0

शायद मुझे कुछ याद आ रहा है, लेकिन इस मामले में 'इवेंट' का नाम बदलकर '_Event' या इस तरह की कुछ और 'EventWithMeta'' को 'ईवेंट' कर दिया जा सकता है। – reclosedev

उत्तर

0

बढ़ावा C++ withn से यह करने के लिए एक तरीका प्रदान नहीं करता है, और ऐसा लगता है कि यह नहीं है की तरह, जाने का रास्ता आवरण वर्गों कि metaclass लागू बनाने के लिए है या कम स्वचालित रूप से instrospection के एक छोटे से बिट usign usign। आइए मान लीजिए कि आपके बूस्ट मॉड्यूल को "इवेंट" नाम दिया गया है - आपको या तो फ़ाइल को _event के रूप में नामित करना चाहिए या इसे मॉड्यूल के अंदर रखना चाहिए, और एक "पायथन फ़ाइल" नामक एक पायथन फ़ाइल लिखें (या आपके मॉड्यूल पर __init__.py फ़ाइल जो अधिक करेगी कम या ज्यादा यह:

import _event 

class eventmeta(type): 
    ... 

event_dict = globals() 
for key, value in _event.__dict__.items(): 
    if isinstance(value, type): 
     event_dict[key] = eventmeta(key, (value,),{}) 
    else: 
     #set other module members as members of this module 
     event_dict[key] = value 

del key, value, event_dict 

Thos cpde स्वचालित रूप से मॉड्यूल चर देशी "_Event" मॉड्यूल में पाए जाने वाले नामों के बराबर सेट हो जाएगा - और प्रत्येक वर्ग यह मुठभेड़ों के लिए, metaclass बदलने, आपका उदाहरण के रूप में एक नया वर्ग बनाने

ऐसा हो सकता है कि आप ऐसा करके मेटाक्लास संघर्ष प्राप्त करें। यदि ऐसा है, तो नव निर्मित वर्गों को मूल वर्गों के लिए प्रॉक्सी होना उचित तरीका है, उचित __getattribute__ बनाकर और __setattr__ विधियां। अगर आपको ऐसा करने की आवश्यकता होगी तो बस एक टिप्पणी में पूछें।

+0

दुर्भाग्यवश, मैं पाइथन में मेटाक्लास को परिभाषित नहीं कर सकता। प्रारंभिकरण को यह करना है कि एक कस्टम आरटीटीआई प्रणाली सी ++ घटनाओं के साथ-साथ पायथन घटनाओं के साथ काम करे। मैं पाइथन को पर्याप्त सी ++ कार्यान्वयन विवरण का पर्दाफाश कर सकता था, इसलिए स्क्रिप्ट आवश्यक प्रारंभिक कार्य कर सकती थी, लेकिन यह सिर्फ एक अच्छा समाधान नहीं है। –

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