क्या करता है -> पायथन फ़ंक्शन परिभाषाओं में इसका मतलब है?


475

मैंने हाल ही में पायथन 3.3 व्याकरण विनिर्देश को देखते हुए कुछ दिलचस्प देखा है :

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

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

def f(x) -> 123:
    return x

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

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

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

जवाबों:


374

यह एक फ़ंक्शन एनोटेशन है

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

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


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

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

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

5
और __annotations__गुण एक शब्दकोश है। कुंजी returnवह है जिसका उपयोग तीर के बाद मान प्राप्त करने के लिए किया जाता है।
कीथ

9
@ डायलेन - शायद इसका कारण यह है कि यह ज्यादातर अप्रयुक्त है क्योंकि अधिकांश अजगर पुस्तकालय अभी भी python2.x के साथ संगत होना चाहते हैं। के रूप में python3.x अधिक मानक बनना शुरू कर देता है, हम इन चीजों को यहां और वहां पॉप-अप करते हुए देख सकते हैं ...
mgilson

251

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

उदाहरण:

>>> 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'}

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

>>> '{:,} {}'.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 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>

86

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

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

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

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

(जोर मेरा)

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

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

def f(x) -> 123:
    return x

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

def f(x) -> int:
    return x

इसके लिए यह प्रभावी रूप से वर्णन करने के लिए कि फ़ंक्शन fएक प्रकार की वस्तु देता है int

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


64

निम्नलिखित कोड में:

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

-> intबस बताता है कि f()एक पूर्णांक देता है (लेकिन यह एक पूर्णांक वापस जाने के लिए समारोह के लिए मजबूर नहीं है)। इसे रिटर्न एनोटेशन कहा जाता है , और इसे एक्सेस किया जा सकता है f.__annotations__['return']

पायथन भी पैरामीटर एनोटेशन का समर्थन करता है:

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

: floatउन लोगों को बताता है जो कार्यक्रम (और कुछ तृतीय-पक्ष पुस्तकालय / कार्यक्रम, उदाहरण pylint) पढ़ते हैं जो xएक होना चाहिए float। इसे एक्सेस किया जाता है f.__annotations__['x'], और इसका कोई मतलब नहीं है। अधिक जानकारी के लिए दस्तावेज़ देखें:

https://docs.python.org/3/reference/compound_stmts.html#function-definitions https://www.python.org/dev/peps/pep-3107/


4

इसका मतलब है कि फ़ंक्शन का प्रकार रिटर्न देता है, लेकिन यह हो सकता है None

यह अजगर 3.x पर उन्मुख आधुनिक पुस्तकालयों में व्यापक है।

उदाहरण के लिए, यह उदाहरण के लिए कई स्थानों पर लाइब्रेरी पांडा-प्रोफाइलिंग के कोड में है :

def get_description(self) -> dict:

def get_rejected_variables(self, threshold: float = 0.9) -> list:

def to_file(self, output_file: Path or str, silent: bool = True) -> None:
"""Write the report to a file.

"इसका मतलब है कि फ़ंक्शन का प्रकार रिटर्न देता है, लेकिन यह कोई भी नहीं हो सकता है।" यह कोई भी या कोई भी प्रकार हो सकता है।
एब्रम शेहता

2

def function(arg)->123:

यह केवल एक रिटर्न प्रकार है, इस मामले में पूर्णांक कोई फर्क नहीं पड़ता कि आप किस नंबर को लिखते हैं।

जावा की तरह :

public int function(int args){...}

लेकिन पाइथन के लिए ( जिम फासरकिस हिलियार्ड ने कैसे कहा) यह केवल एक संकेत है , इसलिए यह वापसी का सुझाव देता है, लेकिन किसी अन्य प्रकार को स्ट्रिंग की तरह वापस करने की अनुमति देता है।


1
def f(x) -> 123:
    return x

मेरा सारांश:

  1. ->डेवलपर्स को वैकल्पिक रूप से फ़ंक्शन के रिटर्न प्रकार को निर्दिष्ट करने के लिए बस शुरू किया जाता है। पायथन एन्हांसमेंट प्रस्ताव 3107 देखें

  2. यह इस बात का संकेत है कि भविष्य में चीजें कैसे विकसित हो सकती हैं क्योंकि पायथन को बड़े पैमाने पर अपनाया जाता है - मजबूत टाइपिंग के लिए एक संकेत - यह मेरा व्यक्तिगत अवलोकन है।

  3. आप तर्कों के लिए भी प्रकार निर्दिष्ट कर सकते हैं। रिटर्न प्रकार के कार्यों और तर्कों को निर्दिष्ट करने से तार्किक त्रुटियों को कम करने और कोड एन्हांसमेंट में सुधार करने में मदद मिलेगी।

  4. आपके पास रिटर्न प्रकार (फ़ंक्शन और पैरामीटर स्तर दोनों के लिए) के रूप में अभिव्यक्तियां हो सकती हैं और अभिव्यक्तियों के परिणाम को एनोटेशन ऑब्जेक्ट की 'रिटर्न' विशेषता के माध्यम से एक्सेस किया जा सकता है । लैम्बडा इनलाइन फ़ंक्शन के लिए एनोटेशन अभिव्यक्ति / रिटर्न वैल्यू के लिए खाली होंगे।


सुधार के लिए धन्यवाद।
maz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.