2015-02-06 8 views
10

में डीफ़, सीडीईएफ और सीपीडीएफ की परिभाषा मैं एक समारोह घोषित करते समय def, cdef और cpdef के बीच अंतर जानना चाहता हूं। डीफ़ और दूसरों के बीच का अंतर यह कम या ज्यादा स्पष्ट है। और मैंने यह भी देखा है कि कभी-कभी इसे घोषणा में वापसी प्रकार जोड़ा जाता है (cdef void/double/int... name) और कभी-कभी नहीं।साइथन

मैं यह भी जानना चाहता हूं कि साइथन में एक स्ट्रिंग चर घोषित कैसे करें, क्योंकि मुझे यह नहीं पता था, मैंने इसे ऑब्जेक्ट के रूप में घोषित किया।

उत्तर

3

def पायथन में एक फ़ंक्शन घोषित करता है। चूंकि साइथन सी रनटाइम पर आधारित है, इसलिए यह आपको cdef और cpdef का उपयोग करने की अनुमति देता है।

cdef सी भाषा की परत में कार्य घोषित करता है। जैसा कि आप सी भाषा में जानते हैं (या नहीं?) आपको प्रत्येक फ़ंक्शन के लिए रिटर्निंग मान को परिभाषित करना होगा। कभी-कभी void के साथ फ़ंक्शन रिटर्न होता है, और यह पाइथन में केवल return के बराबर है।

पायथन एक ऑब्जेक्ट उन्मुख भाषा है। तो अगर आप भी उपवर्गों में सी ++ भाषा की परत में वर्ग विधि परिभाषित कर सकते हैं, और ओवरराइड इस तरीके:

cdef class A: 
    cdef foo(self): 
     print "A" 

cdef class B(A) 
    cdef foo(self, x=None) 
     print "B", x 

cdef class C(B): 
    cpdef foo(self, x=True, int k=3) 
     print "C", x, k 

सारांश, हम क्यों def, cdef और cpdef उपयोग करने के लिए की जरूरत है? क्योंकि यदि आप साइथन का उपयोग करते हैं, तो आपके पायथन कोड को संकलित करने से पहले सी कोड में परिवर्तित कर दिया जाएगा। तो इन चीजों के साथ आप परिणामस्वरूप सी-कोड सूची को नियंत्रित कर सकते हैं।

अधिक जानकारी मैं सुझाव है कि आप आधिकारिक दस्तावेज पढ़ने के लिए के लिए: def कार्यों अजगर और Cython से कहा जा सकता है cdef समारोह से कहा जा सकता है, जबकि: http://docs.cython.org/src/reference/language_basics.html

7

मुख्य अंतर यह है जहां समारोह कहा जा सकता से है Cython और सी

कार्यों के दोनों प्रकार के टाइप और untyped तर्क के किसी भी मिश्रण के साथ घोषित किया जा सकता है, और दोनों ही मामलों में आंतरिक Cython द्वारा सेल्सियस के लिए संकलित किया गया है (और संकलित कोड बहुत, बहुत समान होना चाहिए):

# A Cython class for illustrative purposes 
cdef class C: 
    pass 

def f(int arg1, C arg2, arg3): 
    # takes an integer, a "C" and an untyped generic python object 
    pass 

cdef g(int arg1, C arg2, arg3): 
    pass 

ऊपर दिए गए उदाहरण में, f पाइथन (एक बार यह साइथन मॉड्यूल आयात करने के बाद) दिखाई देगा और g नहीं होगा और पाइथन से नहीं कहा जा सकता है। g की एक सी हस्ताक्षर में अनुवाद होगा:

PyObject* some_name(int, struct __pyx_obj_11name_of_module_C *, PyObject*) 

(जहां struct __pyx_obj_11name_of_module_C * सिर्फ सी struct है कि हमारे वर्ग C में अनुवादित किया गया है)। यह उदाहरण के लिए एक फ़ंक्शन पॉइंटर के रूप में सी कार्यों को पारित करने की अनुमति देता है। इसके विपरीत f (आसानी से) सी से cdef कार्यों पर नहीं कहा जा सकता

प्रतिबंध:

cdef कार्यों अन्य कार्यों के अंदर परिभाषित नहीं किया जा सकता है - यह एक में किसी भी कब्जा कर लिया चर भंडारण का कोई रास्ता नहीं है, क्योंकि सी समारोह सूचक। जैसेनिम्नलिखित कोड अवैध है:

# WON'T WORK! 
def g(a): 
    cdef (int b): 
     return a+b 

cdef कार्यों *args और **kwargs प्रकार तर्क नहीं ले सकते। ऐसा इसलिए है क्योंकि उन्हें आसानी से सी हस्ताक्षर में अनुवादित नहीं किया जा सकता है।

cdef कार्यों

cdef कार्यों के लाभ उन कोई अजगर बराबर (उदाहरण के संकेत के लिए) है कि सहित तर्क के किसी भी प्रकार के ले जा सकते हैं,। def फ़ंक्शंस में ये नहीं हो सकते हैं, क्योंकि उन्हें पायथन से कॉल करने योग्य होना चाहिए।

cdef फ़ंक्शन एक रिटर्न प्रकार भी निर्दिष्ट कर सकते हैं (यदि यह निर्दिष्ट नहीं है तो वे एक पाइथन ऑब्जेक्ट, PyObject* सी में वापस लौटते हैं)। def कार्यों हमेशा एक अजगर वस्तु लौटने के लिए, तो एक वापसी प्रकार निर्दिष्ट नहीं कर सकते:

cdef int h(int* a): 
    # specify a return type and take a non-Python compatible argument 
    return a[0] 

cdef कार्यों def कार्यों से कॉल करने के लिए है क्योंकि वे एक साधारण सी समारोह कॉल करने के लिए अनुवाद कर तेज कर रहे हैं।

cpdef कार्यों

cpdef कार्यों Cython एक cdef समारोह (कि Cython से एक त्वरित समारोह कॉल की अनुमति देता है) और एक def समारोह (जो आप अजगर से यह कॉल करने के लिए अनुमति देता है) उत्पन्न करने के लिए होता है। अंततः def फ़ंक्शन बस cdef फ़ंक्शन पर कॉल करता है। स्वीकृत तर्कों के प्रकारों के संदर्भ में, cpdef कार्यों में cdef और def फ़ंक्शंस दोनों के सभी प्रतिबंध हैं।

जब एक cdef समारोह

उपयोग करने के लिए एक बार समारोह बुलाया गया है वहाँ गति है कि एक cdef अंदर कोड और एक def समारोह में चलाता है में कोई अंतर नहीं है। इसलिए, केवल एक cdef फ़ंक्शन का उपयोग करता है, तो:

  • आप गैर अजगर प्रकार पारित करने के लिए में या बाहर की जरूरत है, या
  • आप सेल्सियस के लिए यह एक समारोह सूचक के रूप में पारित करने के लिए की जरूरत है, या
  • आप बुला रहे हैं यह अक्सर (इसलिए स्पीड-अप फ़ंक्शन कॉल महत्वपूर्ण है) और आपको इसे पायथन से कॉल करने की आवश्यकता नहीं है।

cpdef फ़ंक्शन का उपयोग करें जब आप इसे अक्सर कॉल कर रहे हों (इसलिए स्पैड-अप फ़ंक्शन कॉल महत्वपूर्ण है) लेकिन आपको इसे पायथन से कॉल करने की आवश्यकता है।

+0

मैंने आपके उत्तर का व्याख्या और पुन: उपयोग किया है: https://stackoverflow.com/questions/49172528/should-i-define-my-cython-function-using-def-cdef-or-cpdef-for -ऑप्टिम-प्रदर्शन/49172529 # 49172529 क्या आप शायद इसे दोबारा जांच सकते हैं? – PDiracDelta

+0

@PDiracDelta मैंने इसे देखा था। यह एक उपयोगी प्रश्न/उत्तर संयोजन जैसा दिखता है (मेरी राय में बहुत से लोग 'cdef' का उपयोग करते हैं क्योंकि उन्हें लगता है कि यह किसी भी वास्तविक कारण के लिए स्वचालित रूप से तेज़ नहीं है, इसलिए एक सरल सारांश होना अच्छा है)। मैं कुछ भी नहीं देख सकता जो मैं वहां से असहमत हूं – DavidW