2015-02-26 8 views
9

अजगर कक्षाएं वर्ग हो सकता है विशेषताओं:क्या साइथन एक्सटेंशन प्रकार वर्ग गुणों का समर्थन करते हैं?

class Foo(object): 
    bar = 4 

वहाँ परिभाषित करने वर्ग Cython एक्सटेंशन प्रकारों में विशेषताओं के लिए एक अनुरूप निर्माण है?

thing.c:773:3: error: use of undeclared identifier 'bar' 
    bar = 4; 
^
1 error generated. 
error: command 'cc' failed with exit status 1 
+1

आपको इसे Python 'cdef public int bar' –

+0

से इसे एक्सेस करने के लिए भी सार्वजनिक करने की आवश्यकता है प्रतिक्रिया के लिए धन्यवाद। मुझे नहीं लगता कि मेरे उपयोग के मामले को रन टाइम विचार पर विशेषताओं को जोड़ने पर विचार किया जाएगा। मैं एक बार संकलित समय पर उपलब्ध वर्ग विशेषताओं को परिभाषित करना चाहता हूं। – Pwnosaurus

+0

क्षमा करें हाँ, ध्यान नहीं दे रहा था। मैंने साइथन में कभी भी क्लास एट्रिब्यूट नहीं देखा है। –

उत्तर

1

संक्षिप्त उत्तर हाँ और नहीं है।

नहीं, cdef class में कक्षा विशेषता को जल्दी से सम्मिलित करने के लिए कोई सुविधाजनक वाक्य रचनात्मक मुहावरे नहीं है। हालांकि ....

cython का पूरा बिंदु यह है कि यह आपको निम्न स्तर तक पहुंच प्रदान करता है। अतिरिक्त प्रयास के लिए सामान्य उद्देश्य प्रदर्शन है, लेकिन आप अतिरिक्त स्वतंत्रता वाले चीजों की तरह C भी कर सकते हैं। कठिनाई यह है कि, कई नुकसान हैं, और इस मामले में, आपको बिना किसी काम के शुद्ध python वर्ग विशेषताओं को नहीं मिलेगा। सरल उपयोग मामलों के लिए आपको जो चाहिए उसे प्राप्त करना अभी भी बहुत आसान है।

उदाहरण के लिए, मान लीजिए कि मैं कक्षा के रूप में कुछ गणना इंजन बना रहा हूं और मैं वैश्विक रूप से सभी मामलों के लिए वापसी मूल्य की सटीकता निर्धारित करना चाहता हूं। मैं संकलन समय पर एक डिफ़ॉल्ट चाहता हूं, और समय-समय पर मैं कुछ परीक्षणों को त्वरित रूप से संसाधित करने के लिए इसे कम समायोजित करना चाहता हूं, और फिर इसे अपने अंतिम कार्य के लिए उच्च समायोजित करना चाहता हूं। एक वर्ग विशेषता ऑर्डर करने के लिए किया जाता है, लेकिन आप कार्यक्षमता आप cython में आवश्यकता इस प्रकार प्राप्त कर सकते हैं:

cdef int _precision[1] # storage for my class 'attribute' 
_precision[0]=8   # my default value, set during compilation 

हमें का उपयोग करने के लिए परमिट एक सरणी का उपयोग करना:

पहले, निम्न मॉड्यूल स्तर पर परिभाषित cython idiom precision[0] जो सी *precision के बराबर है। cdef नाम precision स्पष्ट रूप से एक सूचक है क्योंकि डेटा आइटम एक सरणी है। यह cython सिंटैक्टिक मुहावरे का उपयोग cython स्टोरेज स्थानों से पाइथन संदर्भों में कनवर्ट करने की अनुमति देता है। यदि आप चाहते हैं कि एक वैश्विक स्थिरता है जिसे मॉड्यूल में किसी भी कक्षा में cdef कोड द्वारा एक्सेस किया जा सकता है, तो आप कर चुके हैं। यदि आप इसे क्लास एट्रिब्यूट के रूप में सख्ती से उपयोग करना चाहते हैं, तो आपको उस अनुशासन को लागू करना होगा - कंपाइलर परवाह नहीं है।इस बिंदु पर

cdef int* get_precision(): return _precision 
cdef void* set_precision(int i): _precision[0]=i 

:

अब अगर आप भी python कोड से मूल्य समायोजित करना चाहते हैं, तो आप cdef कार्यों कि मॉड्यूल में python कोड 'विशेषता' तक पहुंचने के कॉल कर सकते हैं की एक जोड़ी की आवश्यकता होगी , जब तक आप वास्तव में पसीना नहीं चाहते हैं, तब तक अर्थशास्त्र शुद्ध python से थोड़ा अलग होगा। आप एक python सेटर और गेटर समारोह की जरूरत है, और मुझे लगता है python वर्णनकर्ता गुण द्वारा कार्यान्वित प्रोटोकॉल सबसे आसान है:

cdef class SomeCalculator: 
    ... 

    property precision: 
    def __get__(self): 
     """Get or set calculation precision, default == 8. 
     This is like a class attribute: setting affects all instances, 
     however, it also affects all subclasses.""" 
     return get_precision()[0] 
    def __set__(self,int integer): set_precision(min(30,max(0,integer))) 

पहले 'विशेषता' करने के लिए एक अजगर संदर्भ हो जाता है। दूसरा python अभिन्न मूल्य के साथ 'विशेषता' सेट करता है, जो सीमाओं के भीतर गिरने के लिए पॉलिसीकृत होता है। cython फ़ंक्शन कॉल और रिटर्न इंटरफ़ेस स्वचालित रूप से रूपांतरणों का ख्याल रखता है, जो वे दिखने से अधिक जटिल होते हैं।

उदाहरण के लिए, get_precisionC-pointer देता है। यदि आपने get_precision में dereferencing किया है तो आपको में में python में C-int वापस करने का प्रयास करने में त्रुटि होगी। यदि इसके बजाय आपने __get__ में [0] अव्यवस्था को छोड़ दिया है तो आपको C-pointer वापस करने का प्रयास करने में त्रुटि होगी जैसे कि यह python int था। लिखित के रूप में, स्वचालित रूपांतरण सही प्रकार से मेल खाते हैं। cython इस तरह की चीज के बारे में बहुत ही जटिल है, और चुपचाप गलत मान वापस कर सकता है, केवल रनटाइम पर खोजने योग्य। सही incantation का अनुमान लगाने के लिए कुछ प्रयोग ले सकते हैं।

डॉकस्ट्रिंग आपको शुद्ध python क्लास विशेषता की अपेक्षा न करने के लिए कहता है। यदि आप उप-वर्ग चाहते हैं, और उप-वर्ग एक अलग वैश्विक सेटिंग का उपयोग करते हैं, तो आपको थोड़ा और पसीना पड़ेगा। python में, यह सब स्वचालित रूप से किया जाता है।

फिर भी, अन्य अंतर भी हैं। कक्षा या किसी उदाहरण पर एक वास्तविक श्रेणी विशेषता का संदर्भ दिया जा सकता है। इस संपत्ति को केवल एक उदाहरण पर संदर्भित किया जा सकता है। उदाहरण पर एक वास्तविक श्रेणी विशेषता सेट करना एक उदाहरण विशिष्ट प्रतिलिपि बनाता है, जिससे क्लास विशेषता छेड़छाड़ की जाती है, लेकिन बदले गए उदाहरण के लिए अदृश्य हो जाती है।

दिए गए उपयोग के मामले के लिए, यह काम करता है। एक असली वर्ग विशेषता अनावश्यक है। चूंकि cython कोड आमतौर पर कम सार और गणना गहन है, यह न्यूनतम दृष्टिकोण अक्सर पर्याप्त होता है।

1

आपको लगता है कि जिस तरह से ऐसा नहीं कर सकते: उदाहरण के लिए, जब मैं कोशिश निम्नलिखित cython कोड

cdef class Foo: 
    cdef int bar 
    bar = 4 

मैं इस त्रुटि मिलती है संकलित करने के लिए। मुझे नहीं पता कि स्थैतिक गुण समर्थित हैं, लेकिन "सामान्य" को तरीकों से एक्सेस किया जाना चाहिए, उदा। एक निर्माता:

cdef class Foo: 
    cdef int bar 
    def __init__(self): 
     self.bar = 4 
5

यह सी टाइप स्थिर विशेषताओं को शामिल करना संभव प्रतीत नहीं होता है, Cython एक्सटेंशन प्रकारों नियमित अजगर स्थिर गुण जो भी अजगर में स्वचालित रूप से सुलभ हैं हो सकता है। बस उन्हें घोषित रूप में आप उन्हें अजगर में घोषणा करेंगे:

cdef class Foo: 
    bar = 4 

उत्पन्न कोड से पता चलता है, तो आप उन्हें संदर्भों में जहां सी का उपयोग है कि इन स्थिर विशेषताओं वर्ग वस्तु, यानी की विशेषता dict में अजगर वस्तुओं के रूप में जमा हो जाती है प्रकारों का उपयोग किया जाता है, वे पाइथन वस्तुओं से वापस परिवर्तित कर रहे हैं।

+1

असल में, मुझे संदेह है कि एक स्थिर वर्ग विशेषता जैसा कुछ भी संभव नहीं है * cpython * को छोड़कर * इसके '__dict__' के तत्व के रूप में; तुलना करें: 'टाइप ("माईटाइप", (टाइप,), {' __slots __ ':(' foo ',)}) – SingleNegationElimination

+1

प्रतीत होता है कि ये केवल पढ़ने के लिए हैं। साइथन एक्सटेंशन में वर्ग विशेषताओं को सार्वजनिक रूप से सुलभ बनाने का कोई तरीका है? – Zephyr

+0

उनके लिए एक गेटर और सेटटर परिभाषित करें –

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