2013-01-17 27 views
175

मैं हाल ही में कुछ दिलचस्प देखा है जब Python 3.3 grammar specification को देख:क्या -> पायथन फ़ंक्शन परिभाषाओं में क्या मतलब है?

funcdef: 'def' NAME parameters ['->' test] ':' suite 

वैकल्पिक 'तीर' ब्लॉक अजगर 2 में अनुपस्थित था और मैं पायथन 3. में इसका अर्थ के बारे में कोई जानकारी नहीं मिली यह पता चला यह सही अजगर है और यह दुभाषिया द्वारा स्वीकार कर लिया है:

def f(x) -> 123: 
    return x 

मैंने सोचा था कि यह एक पूर्व शर्त के वाक्य रचना किसी तरह का हो सकता है, लेकिन:

  • मैं यहां x का परीक्षण नहीं कर सकता, अभी भी यह अनिर्धारित है,
  • कोई फर्क नहीं पड़ता कि मैंने तीर के बाद क्या रखा है (उदा। 2 < 1), यह फ़ंक्शन व्यवहार को प्रभावित नहीं करता है।

क्या कोई भी इस वाक्यविन्यास के आदी हो सकता है?

उत्तर

137

यह function annotation है।

अधिक जानकारी में, पायथन 2.x में डॉकस्ट्रिंग्स हैं, जो आपको विभिन्न प्रकार के ऑब्जेक्ट में मेटाडेटा स्ट्रिंग संलग्न करने की अनुमति देती हैं। यह आश्चर्यजनक रूप से आसान है, इसलिए पायथन 3 आपको अपने पैरामीटर का वर्णन करने वाले कार्यों और मूल्यों को वापस करने के लिए मेटाडेटा को संलग्न करने की सुविधा प्रदान करता है।

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

+46

और जानकारी '.__ एनोटेशन__' विशेषता के रूप में उपलब्ध है। –

+1

वाह, मुझे ज्ञान का एक व्यापक क्षेत्र याद आया - न केवल मूल्य एनोटेशन लौटाता है, बल्कि पैरामीटर एनोटेशन भी देता है। आपका बहुत बहुत धन्यवाद :)। – Krotton

+1

@ कपास इसे याद करने के लिए आपको दोष नहीं दे सकता है, यह व्यावहारिक रूप से अप्रयुक्त है। मैंने कभी भी उनका उपयोग करके एक ही पुस्तकालय से मुलाकात की, और यह काफी अस्पष्ट है। – delnan

85

ये PEP 3107 में शामिल फ़ंक्शन एनोटेशन हैं। विशेष रूप से, -> रिटर्न फ़ंक्शन एनोटेशन को चिह्नित करता है।

उदाहरण:

>>> '{:,} {}'.format(kinetic_energy(20,3000), 
     kinetic_energy.__annotations__['return']) 
'90,000,000.0 Joules' 

तुम भी एक अजगर डेटा संरचना हो सकता है के बजाय सिर्फ एक स्ट्रिंग:

>>> rd={'type':float,'units':'Joules','docstring':'Given mass and velocity returns kinetic energy in Joules'} 
>>> def f()->rd: 
... pass 
>>> f.__annotations__['return']['type'] 
<class 'float'> 
>>> f.__annotations__['return']['units'] 
'Joules' 
>>> f.__annotations__['return']['docstring'] 
'Given mass and velocity returns kinetic energy in Joules' 

>>> def kinetic_energy(m:'in KG', v:'in M/S')->'Joules': 
... return 1/2*m*v**2 
... 
>>> kinetic_energy.__annotations__ 
{'return': 'Joules', 'v': 'in M/S', 'm': 'in KG'} 

एनोटेशन शब्दकोशों हैं, तो आप ऐसा कर सकते हैं तो

या, आप कॉल किए गए मानों को सत्यापित करने के लिए फ़ंक्शन विशेषताओं का उपयोग कर सकते हैं:

def validate(func, locals): 
    for var, test in func.__annotations__.items(): 
     value = locals[var] 
     try: 
      pr=test.__name__+': '+test.__docstring__ 
     except AttributeError: 
      pr=test.__name__ 
     msg = '{}=={}; Test: {}'.format(var, value, pr) 
     assert test(value), msg 

def between(lo, hi): 
    def _between(x): 
      return lo <= x <= hi 
    _between.__docstring__='must be between {} and {}'.format(lo,hi)  
    return _between 

def f(x: between(3,10), y:lambda _y: isinstance(_y,int)): 
    validate(f, locals()) 
    print(x,y) 

प्रिंटों

>>> f(2,2) 
AssertionError: x==2; Test: _between: must be between 3 and 10 
>>> f(3,2.1) 
AssertionError: y==2.1; Test: <lambda> 
14

के रूप में अन्य उत्तर कहा है, -> प्रतीक समारोह एनोटेशन के हिस्से के रूप में प्रयोग किया जाता है। पाइथन >= 3.5 के हाल के संस्करणों में, हालांकि, इसमें परिभाषित है।

PEP 3107 -- Function Annotations व्याकरण परिवर्तन को परिभाषित करने, func.__annotations__ का अस्तित्व, जिसमें वे संग्रहीत हैं और तथ्य यह है कि इसका उपयोग अभी भी खुला है, विनिर्देश का वर्णन किया गया है।

पायथन 3.5 में, PEP 484 -- Type Hints इस के लिए एक अर्थ को जोड़ता है: -> फ़ंक्शन लौटने वाले प्रकार को इंगित करने के लिए उपयोग किया जाता है। यह भी लगता है कि इस What about existing uses of annotations में वर्णित के रूप भविष्य के संस्करणों में लागू किया जाएगा: 3.7 में, पूर्ण प्रतिवाद

सबसे तेजी से बोधगम्य योजना 3.6 में गैर प्रकार- संकेत एनोटेशन की मूक प्रतिवाद परिचय होगा घोषित प्रकार संकेत, और पायथन 3.8 में एनोटेशन के एकमात्र अनुमति के रूप में।

(जोर मेरा)

यह वास्तव में 3.6 के रूप में जहाँ तक मैं इतना बता सकते हैं यह भविष्य के संस्करणों के लिए टकरा हो सकता है लागू नहीं किया गया।

इस के अनुसार, उदाहरण आपके द्वारा बताये गये है:

def f(x) -> int: 
    return x 
:

def f(x) -> 123: 
    return x 

भविष्य में मना हो जाएगा (और वर्तमान संस्करण में भ्रमित हो जाएगा), यह आवश्यकता होगी करने के लिए परिवर्तित किया जा सकता

प्रभावी रूप से उस कार्य का वर्णन करने के लिए fint प्रकार का ऑब्जेक्ट देता है।

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

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