टाइपिंग को परिभाषित करने के बीच अंतर। डिक्ट और तानाशाह?


105

मैं पायथन 3.5 में टाइप संकेत का उपयोग कर रहा हूं। मेरा एक सहकर्मी उपयोग करता है typing.Dict:

import typing


def change_bandwidths(new_bandwidths: typing.Dict,
                      user_id: int,
                      user_name: str) -> bool:
    print(new_bandwidths, user_id, user_name)
    return False


def my_change_bandwidths(new_bandwidths: dict,
                         user_id: int,
                         user_name: str) ->bool:
    print(new_bandwidths, user_id, user_name)
    return True


def main():
    my_id, my_name = 23, "Tiras"
    simple_dict = {"Hello": "Moon"}
    change_bandwidths(simple_dict, my_id, my_name)
    new_dict = {"new": "energy source"}
    my_change_bandwidths(new_dict, my_id, my_name)

if __name__ == "__main__":
    main()

वे दोनों ही ठीक काम करते हैं, कोई फर्क नहीं दिखता।

मैंने typingमॉड्यूल प्रलेखन पढ़ा है ।

बीच typing.Dictया dictजो एक मैं इस कार्यक्रम में इस्तेमाल करना चाहिए?


11
ध्यान दें कि पायथन वास्तव में टाइप संकेत को लागू नहीं करता है। वे केवल संकेत हैं , उनका उपयोग रनटाइम पर नहीं किया जाता है, या यहां तक ​​कि समय को संकलित करने के लिए, प्रकारों को लागू करने के लिए। अजगर को दृढ़ता से टाइप किया जा सकता है (कमजोर टाइपिंग के विपरीत), यह गतिशील रूप से टाइप (सख्त टाइपिंग के विपरीत) भी होता है। देखें Is अजगर दृढ़ता से टाइप किया है? । माईपी जैसे बाहरी उपकरण इन संकेतों का उपयोग आपको बेहतर कोड लिखने में मदद करने के लिए कर सकते हैं, हालांकि, स्थिर विश्लेषण नामक प्रक्रिया में।
मार्टिन पीटर्स

1
@MartijnPieters मुझे MyPy के साथ अपने कोड में टाइप संकेत का उपयोग करने के लिए प्यार करता था और दिखावा करता था कि मैं टाइप सुरक्षा के साथ पायथन का उपयोग कर सकता हूं। दुर्भाग्य से यह मुझे ए) कोड मिला जो <3.4 और बी पर काम नहीं करता है) लोग मुझ पर हंस रहे हैं क्योंकि जाहिर है, टाइप संकेत एक हंसी का पात्र हैं। यह वास्तव में काफी दुर्भाग्यपूर्ण है।
बिल्ली

3
@cat: एक फेसबुक कर्मचारी द्वारा पाइथन को टाइप हिंटिंग के लिए पेश किया गया था, क्योंकि PHP ( हैक देखें ) में एक ही फीचर जोड़ने के साथ हमें बड़ी सफलता मिली थी । हंसने वाले किसी भी व्यक्ति ने कभी भी मुट्ठी भर इंजीनियरों से बड़ा प्रोजेक्ट नहीं बनाया है।
मार्टिन पीटर्स

3
@MartijnPieters नहीं, def a(b: int) -> bool:पायथन 2.7 में एक सिंटैक्स त्रुटि है, और मुझे लगता है कि यह पायथन 3 के पुराने संस्करणों में भी सिंटैक्स त्रुटि है।
बिल्ली

1
@cat: आप यहाँ फ़ंक्शन एनोटेशन के बारे में बात कर रहे हैं, वाक्यविन्यास जो पायथन 3.0 में जोड़ा गया था। तो एकमात्र संस्करण जहां वह वाक्यविन्यास त्रुटि 2.7 है, यही कारण है कि mypy टिप्पणियों में उस जानकारी को डालने का समर्थन करता है।
मार्टिन पीटर्स

जवाबों:


147

सादे typing.Dictऔर dict, का उपयोग करने के बीच कोई वास्तविक अंतर नहीं है।

हालाँकि, typing.Dictएक सामान्य प्रकार * है जो आपको कुंजी और मान के प्रकार को भी निर्दिष्ट करने देता है , जिससे यह अधिक लचीला हो जाता है:

def change_bandwidths(new_bandwidths: typing.Dict[str, str],
                      user_id: int,
                      user_name: str) -> bool:

इस तरह, यह अच्छी तरह से हो सकता है कि आपके प्रोजेक्ट जीवनकाल के कुछ बिंदु पर आप डिक्शनरी तर्क को थोड़ा और सटीक रूप से परिभाषित करना चाहते हैं, जिस बिंदु पर विस्तार typing.Dictकरने typing.Dict[key_type, value_type]का स्थान बदलने की तुलना में एक 'छोटा' परिवर्तन है dict

आप यहां Mappingया MutableMappingप्रकारों का उपयोग करके इसे और भी सामान्य बना सकते हैं; चूंकि आपके फ़ंक्शन को मैपिंग को बदलने की आवश्यकता नहीं है , इसलिए मैं इसके साथ रहना चाहूंगा Mapping। A dictएक मैपिंग है, लेकिन आप अन्य ऑब्जेक्ट्स बना सकते हैं जो मैपिंग इंटरफ़ेस को संतुष्ट करते हैं, और आपका फ़ंक्शन अभी भी उन लोगों के साथ काम कर सकता है:

def change_bandwidths(new_bandwidths: typing.Mapping[str, str],
                      user_id: int,
                      user_name: str) -> bool:

अब आप इस फ़ंक्शन के अन्य उपयोगकर्ताओं को स्पष्ट रूप से बता रहे हैं कि आपका कोड वास्तव में पास किए गए मैपिंग में परिवर्तन नहीं करेगा new_bandwidths

आपका वास्तविक कार्यान्वयन केवल एक ऐसी वस्तु की अपेक्षा कर रहा है जो मुद्रण योग्य हो। यह एक परीक्षण कार्यान्वयन हो सकता है, लेकिन जैसा कि यह खड़ा है कि यदि आप उपयोग करते हैं तो आपका कोड काम करना जारी रखेगा new_bandwidths: typing.Any, क्योंकि पायथन में कोई भी वस्तु मुद्रण योग्य है।


* : नोट: यदि आप पायथॉन 3.7 या नए का उपयोग कर रहे हैं, तो आप dictएक सामान्य प्रकार के रूप में उपयोग कर सकते हैं यदि आप अपने मॉड्यूल को शुरू करते हैं from __future__ import annotations, और पायथन 3.9 के रूप में, dict(साथ ही अन्य मानक कंटेनरों) का उपयोग जेनेरिक प्रकार के रूप में किया जा रहा है, उसके बिना भी निर्देशन


2
उपयोगी अतिरिक्त उदाहरण तब होंगे जब शब्दकोश मान अलग-अलग प्रकार के हो सकते हैं {"name": "bob", "age" : 51}, उदाहरण के लिए , क्या यह कुछ ऐसा होगा typing.Mapping[Union[str, int]? एक नेस्टेड डिक्शनरी के बारे में क्या {"person": {"name":"bob", "age": 51}ऐसा कुछ होगा typing.Mapping[str, typing.Mapping[Union[str, int]]? Unionउस तरह का उपयोग करना मुझे परेशान करता है क्योंकि यह एक सख्त स्कीमा नहीं है क्योंकि कोई आदेश नहीं है। शायद यह ठीक है, या कोई विकल्प है?
दावोस

1
इस Unionसवाल के बारे में कोई बात नहीं कि मुझे अभी भी एक खुली चर्चा है github.com/python/typing/issues/28
Davos

1
यह बहुत ही रोचक, उपयोगी और संबंधित python.org/dev/peps/pep-0589 लगता है
ग्रेग हिल्स्टन

@GregHilston: यह वास्तव में इस बात के बारे में है कि एक शब्दकोश में क्या कुंजियाँ प्रतिबंधित की जा सकती हैं, और यह निर्दिष्ट करें कि प्रत्येक संबद्ध मूल्य में किस प्रकार का होना चाहिए।
मार्टिन पीटर्स

1
@GregHilston: आह, हाँ, यह है।
मार्टिन पीटर्स

26

typing.Dictइसका एक सामान्य संस्करण है dict:

class typing.Dict(dict, MutableMapping[KT, VT])

तानाशाही का एक सामान्य संस्करण। इस प्रकार का उपयोग इस प्रकार है:

def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
     return word_list[word]

यहां आप प्रमुख और मूल्यों के प्रकार को निर्दिष्ट कर सकते हैं: Dict[str, int]

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