पायथन 3.5 में किस प्रकार के संकेत हैं?


250

पायथन 3.5 में सबसे अधिक चर्चित सुविधाओं में से एक टाइप संकेत है

इस लेख में टाइप संकेत का एक उदाहरण उल्लेख किया गया है और यह भी जिम्मेदारी से टाइप संकेत का उपयोग करने का उल्लेख करते समय। क्या कोई उनके बारे में अधिक समझा सकता है और उन्हें कब इस्तेमाल किया जाना चाहिए और कब नहीं?


4
आपको पीईपी 484 पर एक नज़र डालनी चाहिए जो आधिकारिक चैंज से जुड़ा हुआ है ।
स्टीफन

1
@AvashRaj: रिलीज़ के बारे में एक अच्छी चर्चा यहाँ
वालस्टीन

1
यह अफ़सोस की बात है कि C-API उपयोग के मामले को इस PEP 484 द्वारा पूरी तरह से अनदेखा किया गया है, विशेष रूप से साइथन और नुम्बा के लिए संकेत।
denfromufa

जवाबों:


343

मेरा सुझाव है कि PEP 483 और PEP 484 पढ़ना और टाइप हिंटिंग पर गुइडो द्वारा इस प्रस्तुति को देखना ।

संक्षेप में : टाइप हिंटिंग का शाब्दिक अर्थ है कि शब्दों का क्या अर्थ है, आप उस वस्तु (प्रकार) का संकेत देते हैं जिसका आप उपयोग कर रहे हैं

पायथन की गतिशील प्रकृति के कारण , उपयोग की जा रही वस्तु के प्रकार की जाँच या जाँच विशेष रूप से कठिन है। यह तथ्य डेवलपर्स के लिए यह समझना कठिन बना देता है कि वास्तव में उस कोड में क्या चल रहा है जो उन्होंने नहीं लिखा है और सबसे महत्वपूर्ण बात यह है कि कई IDE में पाए गए प्रकार के चेकिंग टूल के लिए [PyCharm, PyDev का ध्यान रखें] जो इस तथ्य के कारण सीमित हैं उनके पास कोई संकेतक नहीं है कि वस्तुएं किस प्रकार की हैं। परिणामस्वरूप वे लगभग 50% सफलता दर के साथ टाइप करने की कोशिश कर रहे हैं (जैसा कि प्रस्तुति में बताया गया है)।


टाइप हिंटिंग प्रस्तुति से दो महत्वपूर्ण स्लाइड्स लेने के लिए:

संकेत क्यों लिखें?

  1. टाइप चेकर्स की मदद करता है: आप किस प्रकार का ऑब्जेक्ट चाहते हैं, इस पर इशारा करके, चेक परीक्षक आसानी से पता लगा सकता है कि, उदाहरण के लिए, आप किसी ऑब्जेक्ट को उस प्रकार से पास कर रहे हैं जो अपेक्षित नहीं है।
  2. दस्तावेज़ीकरण में मदद करता है: आपके कोड को देखने वाला एक तीसरा व्यक्ति यह जान सकेगा कि क्या अपेक्षित है, जहाँ, बिना, उन्हें प्राप्त किए बिना इसका उपयोग कैसे किया जाए TypeErrors
  3. IDEs को अधिक सटीक और मजबूत उपकरण विकसित करने में मदद करता है: विकास वातावरण उचित तरीकों का सुझाव देने में बेहतर अनुकूल होगा जब आपको पता होगा कि आपकी वस्तु किस प्रकार की है। आपने शायद किसी बिंदु पर कुछ आईडीई के साथ यह अनुभव किया है, .जिसमें किसी वस्तु के लिए परिभाषित नहीं किए गए तरीकों / विशेषताओं को मारना और रखना है ।

स्टेटिक टाइप चेकर्स का उपयोग क्यों करें?

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

इस छोटे से परिचय के लिए एक समापन नोट के रूप में : यह एक वैकल्पिक विशेषता है और, जो मैं समझता हूं, उसे स्थिर टाइपिंग के कुछ लाभों को प्राप्त करने के लिए पेश किया गया है।

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


टाइप करें

इस उत्तर को और अधिक पूर्ण बनाने के लिए, मुझे लगता है कि थोड़ा प्रदर्शन उपयुक्त होगा। मैं उपयोग कर रहा हूँ mypy, पुस्तकालय जो टाइप संकेत को प्रेरित करते हैं क्योंकि वे पीईपी में प्रस्तुत किए जाते हैं। यह मुख्य रूप से इस प्रश्न से टकरा रहा है और सोच रहा है कि कहां से शुरू किया जाए।

इससे पहले कि मैं ऐसा करूं, मैं निम्नलिखित बातों को दोहरा दूं: पीईपी 484 कुछ भी लागू नहीं करता है; यह केवल फ़ंक्शन एनोटेशन के लिए एक दिशा निर्धारित कर रहा है और किस प्रकार की जाँच / प्रदर्शन किया जा सकता है, इसके लिए दिशानिर्देशों का प्रस्ताव कर रहा है। आप अपने कार्यों को एनोटेट कर सकते हैं और जितनी चाहें उतनी चीजें इंगित कर सकते हैं; आपकी स्क्रिप्ट अभी भी एनोटेशन की मौजूदगी की परवाह किए बिना चलेगी क्योंकि पायथन खुद उनका उपयोग नहीं करता है।

वैसे भी, पीईपी में उल्लिखित, संकेत प्रकार आमतौर पर तीन रूप लेने चाहिए:

इसके अतिरिक्त, आप नए typingमॉड्यूल के साथ संयोजन में टाइप संकेत का उपयोग करना चाहते हैं Py3.5। इसमें, कई (अतिरिक्त) एबीसी (एब्सट्रैक्ट बेस क्लास) को स्थैतिक जाँच में उपयोग के लिए सहायक कार्यों और सज्जाकारों के साथ परिभाषित किया गया है। अधिकांश ABCsमें collections.abcशामिल हैं, लेकिन Genericसदस्यता की अनुमति देने के लिए एक __getitem__()तरीके से (एक विधि को परिभाषित करके )।

इनमें से अधिक गहराई से व्याख्या करने में रुचि रखने वाले किसी व्यक्ति के लिए, mypy documentationबहुत अच्छी तरह से लिखा गया है और उनके चेकर की कार्यक्षमता का प्रदर्शन / वर्णन करते हुए बहुत सारे कोड नमूने हैं; यह निश्चित रूप से पढ़ने लायक है।

समारोह एनोटेशन और विशेष टिप्पणी:

सबसे पहले, विशेष टिप्पणियों का उपयोग करते समय हम कुछ व्यवहार का निरीक्षण करना दिलचस्प है। # type: typeकिसी वस्तु के प्रकार को इंगित करने के लिए चर असाइनमेंट के दौरान विशेष टिप्पणियां जोड़ी जा सकती हैं यदि कोई सीधे अनुमान नहीं लगाया जा सकता है। साधारण असाइनमेंट आम तौर पर आसानी से अनुमानित होते हैं, लेकिन अन्य, जैसे सूचियां (उनकी सामग्री के संबंध में), नहीं कर सकते।

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

# generic List, supports indexing.
from typing import List

# In this case, the type is easily inferred as type: int.
i = 0

# Even though the type can be inferred as of type list
# there is no way to know the contents of this list.
# By using type: List[str] we indicate we want to use a list of strings.
a = []  # type: List[str]

# Appending an int to our list
# is statically not correct.
a.append(i)

# Appending a string is fine.
a.append("i")

print(a)  # [0, 'i']

यदि हम इन कमांड्स को एक फाइल में जोड़ते हैं और अपने दुभाषिया के साथ निष्पादित करते हैं, तो सब कुछ ठीक काम करता है और print(a)बस सूची की सामग्री को प्रिंट करता है a# typeटिप्पणियां निकाल दिया गया है, सादा टिप्पणी जो कोई अतिरिक्त अर्थ अर्थ के रूप में इलाज

mypyदूसरी ओर, इसे चलाने से , हमें निम्नलिखित प्रतिक्रिया मिलती है:

(Python3)jimmi@jim: mypy typeHintsCode.py
typesInline.py:14: error: Argument 1 to "append" of "list" has incompatible type "int"; expected "str"

यह इंगित करना कि strवस्तुओं की एक सूची में ए नहीं हो सकता है int, जो, सांख्यिकीय रूप से बोल रहा है, ध्वनि है। यह या तो aकेवल और केवल आकर्षक strवस्तुओं के प्रकार का पालन करके या यह aइंगित करने के लिए सामग्री के प्रकार को बदलकर तय किया जा सकता है कि कोई भी मूल्य स्वीकार्य है ( List[Any]बाद Anyमें आयात किया गया है typing)।

फ़ंक्शन एनोटेशन param_name : typeआपके फ़ंक्शन हस्ताक्षर में प्रत्येक पैरामीटर के बाद फॉर्म में जोड़े जाते हैं और -> typeअंतिम फ़ंक्शन कॉलन से पहले नोटेशन का उपयोग करके रिटर्न प्रकार निर्दिष्ट किया जाता है ; सभी एनोटेशन __annotations__एक आसान शब्दकोश रूप में उस फ़ंक्शन के लिए विशेषता में संग्रहीत किए जाते हैं । एक तुच्छ उदाहरण का उपयोग करना (जिसमें typingमॉड्यूल से अतिरिक्त प्रकार की आवश्यकता नहीं है ):

def annotated(x: int, y: str) -> bool:
    return x < y

annotated.__annotations__विशेषता अब निम्न मान है:

{'y': <class 'str'>, 'return': <class 'bool'>, 'x': <class 'int'>}

यदि हम पूरी तरह से नॉबी हैं, या हम Py2.7अवधारणाओं से परिचित हैं और इसके परिणामस्वरूप TypeErrorकी तुलना में गुप्त हैं annotated, तो हम एक और स्थैतिक जाँच कर सकते हैं, त्रुटि पकड़ सकते हैं और हमें कुछ परेशानी से बचा सकते हैं:

(Python3)jimmi@jim: mypy typeHintsCode.py
typeFunction.py: note: In function "annotated":
typeFunction.py:2: error: Unsupported operand types for > ("str" and "int")

अन्य बातों के साथ, फ़ंक्शन को अमान्य तर्कों के साथ कॉल करना भी पकड़ा जाएगा:

annotated(20, 20)

# mypy complains:
typeHintsCode.py:4: error: Argument 2 to "annotated" has incompatible type "int"; expected "str"

इन्हें मूल रूप से किसी भी उपयोग के मामले में बढ़ाया जा सकता है और पकड़ी गई त्रुटियों को मूल कॉल और संचालन से आगे बढ़ाया जा सकता है। आप जिन प्रकारों की जांच कर सकते हैं, वे वास्तव में लचीले हैं और मैंने केवल इसकी क्षमता का एक छोटा सा शिखर दिया है। typingमॉड्यूल, PEPs या mypyडॉक्स में एक नज़र आपको पेश की गई क्षमताओं का अधिक व्यापक विचार देगा।

स्टब फ़ाइलें:

स्टब फ़ाइलों को दो अलग-अलग गैर-विशिष्ट अनन्य मामलों में उपयोग किया जा सकता है:

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

स्टब फाइल्स (विस्तार के साथ .pyi) जो मॉड्यूल आप बना रहे हैं, उसका एनोटेट इंटरफेस है / उपयोग करना चाहते हैं। वे उन कार्यों के हस्ताक्षर होते हैं जिन्हें आप छोड़ दिए गए कार्यों के शरीर के साथ टाइप करना चाहते हैं। इसे महसूस करने के लिए, एक मॉड्यूल में तीन यादृच्छिक कार्यों का एक सेट दिया गया है randfunc.py:

def message(s):
    print(s)

def alterContents(myIterable):
    return [i for i in myIterable if i % 2 == 0]

def combine(messageFunc, itFunc):
    messageFunc("Printing the Iterable")
    a = alterContents(range(1, 20))
    return set(a)

हम एक स्टब फ़ाइल बना सकते हैं randfunc.pyi, जिसमें हम कुछ प्रतिबंध लगा सकते हैं यदि हम ऐसा करना चाहते हैं। नकारात्मक पक्ष यह है कि स्टब के बिना स्रोत को देखने वाला व्यक्ति वास्तव में उस एनोटेशन सहायता को प्राप्त नहीं करेगा जब यह समझने की कोशिश कर रहा है कि कहाँ पारित किया जाना चाहिए।

वैसे भी, एक स्टब फ़ाइल की संरचना बहुत सरल है: खाली निकायों ( passभरे हुए) के साथ सभी फ़ंक्शन परिभाषाएं जोड़ें और अपनी आवश्यकताओं के आधार पर एनोटेशन की आपूर्ति करें। यहाँ, मान लें कि हम केवल intअपने कंटेनरों के प्रकारों के साथ काम करना चाहते हैं ।

# Stub for randfucn.py
from typing import Iterable, List, Set, Callable

def message(s: str) -> None: pass

def alterContents(myIterable: Iterable[int])-> List[int]: pass

def combine(
    messageFunc: Callable[[str], Any],
    itFunc: Callable[[Iterable[int]], List[int]]
)-> Set[int]: pass

combineफ़ंक्शन इस बात का संकेत देता है कि आप किसी भिन्न फ़ाइल में एनोटेशन का उपयोग क्यों करना चाहते हैं, वे कुछ बार कोड को अव्यवस्थित करते हैं और पठनीयता को कम करते हैं (पायथन के लिए बड़ा नहीं-नहीं)। आप निश्चित रूप से प्रकार के उपनामों का उपयोग कर सकते हैं, लेकिन कभी-कभी यह मदद करने से अधिक भ्रमित करता है (इसलिए उन्हें बुद्धिमानी से उपयोग करें)।


यह आपको पायथन में टाइप संकेत की मूल अवधारणाओं से परिचित होना चाहिए। भले ही टाइप चेकर का उपयोग किया गया हो, mypyआपको धीरे-धीरे उनमें से अधिक पॉप-अप, कुछ आंतरिक रूप से IDE ( PyCharm ) और अन्य को मानक अजगर मॉड्यूल के रूप में देखना शुरू करना चाहिए । मैं निम्नलिखित सूची में अतिरिक्त चेकर्स / संबंधित पैकेजों को जोड़ने और जोड़ने की कोशिश करूंगा जब मैं उन्हें (या यदि सुझाव दिया गया हो)।

चेकर्स मुझे पता है :

  • Mypy : यहाँ वर्णित है।
  • PyType : Google द्वारा, मैं जो भी इकट्ठा करता हूं, उससे अलग नोटेशन का उपयोग करता है, शायद देखने लायक।

संबंधित पैकेज / परियोजनाएं :

  • टाइप किया गया: आधिकारिक पायथन रेपो, मानक पुस्तकालय के लिए स्टब फ़ाइलों का वर्गीकरण।

यह typeshedपरियोजना वास्तव में सबसे अच्छी जगहों में से एक है जिसे आप यह देखने के लिए देख सकते हैं कि अपने स्वयं के प्रोजेक्ट में किस प्रकार का उपयोग किया जा सकता है। आइए एक उदाहरण के__init__Counter रूप में संबंधित .pyiफ़ाइल में वर्ग के डंडर्स लेते हैं :

class Counter(Dict[_T, int], Generic[_T]):
        @overload
        def __init__(self) -> None: ...
        @overload
        def __init__(self, Mapping: Mapping[_T, int]) -> None: ...
        @overload
        def __init__(self, iterable: Iterable[_T]) -> None: ...

_T = TypeVar('_T')जेनेरिक कक्षाओं को परिभाषित करने के लिए कहां उपयोग किया जाता है । के लिए Counterवर्ग हम देख सकते हैं कि यह या तो, अपने प्रारंभकर्ता में कोई तर्क ले एक भी प्राप्त कर सकते हैं Mappingएक करने के लिए किसी भी प्रकार से int या एक ले Iterableकिसी भी प्रकार की।


सूचना : एक बात जिसका मैं उल्लेख करना भूल गया था कि typingमॉड्यूल को अनंतिम आधार पर पेश किया गया है । से पीईपी 411 :

एक अनंतिम पैकेज में एक "स्थिर" स्थिति में "स्नातक" करने से पहले इसका एपीआई संशोधित हो सकता है। एक ओर, यह राज्य पैकेज को औपचारिक रूप से पायथन वितरण का हिस्सा होने के लाभ प्रदान करता है। दूसरी ओर, कोर डेवलपमेंट टीम स्पष्ट रूप से बताती है कि पैकेज की एपीआई की स्थिरता के संबंध में कोई वादा नहीं किया गया है, जो अगले रिलीज के लिए बदल सकता है। हालांकि इसे एक असंभावित परिणाम माना जाता है, इस तरह के पैकेज को मानक पुस्तकालय से बिना पदावनति अवधि के भी हटाया जा सकता है यदि उनके एपीआई या रखरखाव के बारे में चिंताएं अच्छी तरह से स्थापित साबित होती हैं।

तो नमक की एक चुटकी के साथ यहां चीजें ले लो; मुझे संदेह है कि इसे हटा दिया जाएगा या महत्वपूर्ण तरीकों से बदल दिया जाएगा, लेकिन कभी पता नहीं चल सकता है।


** एक अन्य विषय पूरी तरह से लेकिन टाइप-हिंट के दायरे में मान्य है PEP 526: वैरिएंट एनोटेशन्स के लिए सिंटैक्स# type नए सिंटैक्स की शुरुआत करके टिप्पणियों को बदलने का एक प्रयास है जो उपयोगकर्ताओं को सरल varname: typeबयानों में वेरिएबल के प्रकार को एनोटेट करने की अनुमति देता है ।

देखें कि पाइथन 3.6 में परिवर्तनीय एनोटेशन क्या हैं? , जैसा कि पहले उल्लेख किया गया है, इन पर एक छोटे से परिचय के लिए।


3
"पायथन की अत्यधिक गतिशील प्रकृति के कारण, उपयोग की जा रही वस्तु के प्रकार की जाँच या जाँच विशेष रूप से कठिन है।" आप स्थैतिक जाँच की बात कर रहे हैं, है ना?
bsam

53

जिम के विस्तृत जवाब में जोड़ना:

typingमॉड्यूल की जाँच करें - यह मॉड्यूल PEP 484 द्वारा निर्दिष्ट प्रकार के संकेत का समर्थन करता है ।

उदाहरण के लिए, नीचे दिया गया फ़ंक्शन प्रकार के मान लेता है और लौटाता है और strनिम्नानुसार एनोटेट किया जाता है:

def greeting(name: str) -> str:
    return 'Hello ' + name

typingमॉड्यूल भी समर्थन करता है:

  1. अलियासिंग टाइप करें
  2. कॉलबैक फ़ंक्शंस के लिए टाइप करें ।
  3. जेनरिक - कंटेनर तत्वों के लिए अपेक्षित प्रकारों को निरूपित करने के लिए सदस्यता का समर्थन करने के लिए सार आधार वर्गों का विस्तार किया गया है।
  4. उपयोगकर्ता-परिभाषित सामान्य प्रकार - एक उपयोगकर्ता-परिभाषित वर्ग को सामान्य वर्ग के रूप में परिभाषित किया जा सकता है।
  5. कोई भी प्रकार - हर प्रकार किसी भी का एक उपप्रकार है।

26

हाल ही में जारी PyCharm 5 टाइप हिंटिंग का समर्थन करता है। इसके बारे में अपने ब्लॉग पोस्ट में ( PyCharm 5 में पायथन 3.5 प्रकार की हिंटिंग देखें ) वे इस बात का एक शानदार विवरण प्रस्तुत करते हैं कि किस प्रकार के संकेत हैं और आपके कोड में उनका उपयोग करने के लिए कई उदाहरणों और उदाहरणों के साथ नहीं हैं

इसके अतिरिक्त, यह पायथन 2.7 में समर्थित है, जैसा कि इस टिप्पणी में बताया गया है :

PyCharm PythI से Python 2.7, Python 3.2-3.4 के लिए टाइपिंग मॉड्यूल का समर्थन करता है। 2.7 के लिए आपको * .pyi स्टब फ़ाइलों में टाइप संकेत लगाने होंगे क्योंकि पायथन 3.0 में फ़ंक्शन एनोटेशन जोड़े गए थे


0

टाइप हिंट एक गतिशील भाषा के लिए एक हालिया जोड़ है जहां दशकों से लोगों ने हंगरियन के रूप में सरल नामकरण सम्मेलनों को शपथ ली है (ऑब्जेक्ट पहले अक्षर बी = बुलियन, सी = चरित्र, डी = शब्दकोश, आई = पूर्णांक, एल = सूची, एन / सांख्यिक के साथ वस्तु लेबल) , s = string, t = tuple) की जरूरत नहीं थी, बहुत बोझिल, लेकिन अब तय कर लिया है कि, ओह इंतजार ... यह वस्तुओं को पहचानने के लिए भाषा (प्रकार) का उपयोग करने के लिए बहुत अधिक परेशानी है, और हमारे फैंसी आईडीई कुछ भी करने में मदद की ज़रूरत है जो जटिल है, और यह कि गतिशील रूप से असाइन किए गए ऑब्जेक्ट मान उन्हें किसी भी तरह से पूरी तरह से बेकार कर देते हैं, जबकि एक साधारण नामकरण सम्मेलन सभी को हल कर सकता है, किसी भी डेवलपर के लिए, केवल एक नज़र में।


फ्रैंक होने के लिए, यह उत्तर की तुलना में एक शेख़ी की तरह लगता है।
दिमित्री फासरकिस हिलियार्ड

-1

टाइप-संकेत स्थिरता के लिए हैं और पायथन द्वारा व्याख्या नहीं की जाती है। नीचे दिए गए कोड में, def add(self, ic:int)अगली return...पंक्ति तक लाइन में कोई त्रुटि नहीं होती है :

class C1:
    def __init__(self):
        self.idn = 1
    def add(self, ic: int):
        return self.idn + ic
    
c1 = C1()
c1.add(2)

c1.add(c1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 5, in add
TypeError: unsupported operand type(s) for +: 'int' and 'C1'
 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.