2012-02-16 8 views
20

एक वर्ग सदस्य चर को पाइथन में एक विशिष्ट प्रकार के रूप में कैसे प्रतिबंधित कर सकता है?बल/सुनिश्चित करें कि पाइथन वर्ग विशेष प्रकार


अधिक बड़ा संस्करण:

मैं एक वर्ग कई सदस्य चर जो वर्ग के लिए बाहर से स्थापित कर रहे हैं है कि है। जिस तरह से उनका उपयोग किया जाता है, उनके कारण वे विशिष्ट प्रकार, या तो int या सूची होना चाहिए। यदि यह सी ++ था, तो मैं उन्हें केवल निजी बना दूंगा और 'सेट' फ़ंक्शन में टाइप-चेकिंग करूँगा। यह देखते हुए कि यह संभव नहीं है, क्या चर के प्रकार को प्रतिबंधित करने का कोई तरीका है ताकि रनटाइम पर त्रुटि/अपवाद हो, यदि उन्हें गलत प्रकार का मान असाइन किया गया हो? या क्या मुझे उनके उपयोग को हर फंक्शन के भीतर जांचने की ज़रूरत है?

धन्यवाद।

+3

पाइथोनिक तरीका कक्षा को उचित रूप से दस्तावेज करना है। यदि गलत ऑब्जेक्ट प्रकार सेट किया गया है, तो कोड वैसे भी असफल हो जाएगा। दूसरी तरफ उपयोगकर्ता एक ऐसे प्रकार का उपयोग कर सकता है जो आपके 'इंस्टेंसेंस' चेक को पास नहीं करेगा लेकिन अन्यथा ठीक है (बतख टाइपिंग)। – yak

उत्तर

30

आप अन्य जवाब की तरह एक संपत्ति का उपयोग कर सकते डाल दिया - इसलिए, यदि आप एक विशेषता constraina को कहते हैं, "बार" और एक पूर्णांक के लिए यह विवश हैं, तो आप इस तरह कोड लिख सकते हैं:

class Foo(object): 
    def _get_bar(self): 
     return self.__bar 
    def _set_bar(self, value): 
     if not isinstance(value, int): 
      raise TypeError("bar must be set to an integer") 
     self.__bar = value 
    bar = property(_get_bar, _set_bar) 

और यह काम करता है:

>>> f = Foo() 
>>> f.bar = 3 
>>> f.bar 
3 
>>> f.bar = "three" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in _set_bar 
TypeError: bar must be set to an integer 
>>> 

(वहाँ भी गुण लेखन, "संपत्ति" में निर्मित गेटर पद्धति के लिए एक डेकोरेटर के रूप में उपयोग करने का एक नया तरीका है - लेकिन मैं पुराना तरीका पसंद करते हैं, जैसे मैंने इसे ऊपर रखा)।

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

def getter_setter_gen(name, type_): 
    def getter(self): 
     return getattr(self, "__" + name) 
    def setter(self, value): 
     if not isinstance(value, type_): 
      raise TypeError("%s attribute must be set to an instance of %s" % (name, type_)) 
     setattr(self, "__" + name, value) 
    return property(getter, setter) 

def auto_attr_check(cls): 
    new_dct = {} 
    for key, value in cls.__dict__.items(): 
     if isinstance(value, type): 
      value = getter_setter_gen(key, value) 
     new_dct[key] = value 
    # Creates a new class, using the modified dictionary as the class dict: 
    return type(cls)(cls.__name__, cls.__bases__, new_dct) 

और तुम सिर्फ एक वर्ग के रूप में डेकोरेटर auto_attr_check उपयोग करें, और गुण वर्ग शरीर में आप चाहते हैं declar प्रकार गुण भी बाध्य करने की आवश्यकता के बराबर होना चाहिए:

...  
... @auto_attr_check 
... class Foo(object): 
...  bar = int 
...  baz = str 
...  bam = float 
... 
>>> f = Foo() 
>>> f.bar = 5; f.baz = "hello"; f.bam = 5.0 
>>> f.bar = "hello" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in setter 
TypeError: bar attribute must be set to an instance of <type 'int'> 
>>> f.baz = 5 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in setter 
TypeError: baz attribute must be set to an instance of <type 'str'> 
>>> f.bam = 3 + 2j 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in setter 
TypeError: bam attribute must be set to an instance of <type 'float'> 
>>> 
+1

धन्यवाद! अच्छी तरह से काम। – thornate

+0

क्या कई प्रकार के चेक होने का एक आसान तरीका है, उदा। बार = int या फ्लोट? – mysteryDate

+0

इंस्टेंसेंस उदाहरणों का एक ट्यूपल स्वीकार करता है - चूंकि इसे इस कोड पर बुलाया जाता है, इसलिए आप बस वहां के प्रकार के टुपल का उपयोग कर सकते हैं - इसे केवल काम करना चाहिए: 'bar = int, float' – jsbueno

1

आप उसी प्रकार के property का उपयोग कर सकते हैं जैसा कि आपने सी ++ में उल्लेख किया है। आपको http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/ से संपत्ति के लिए सहायता मिलेगी।

+0

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

+0

लिंक केवल उत्तर खराब हैं, और वास्तव में लिंक टूट गया है। – Antonio

1

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

आप गुणों का उपयोग कर सकते हैं, जैसा कि अन्य उत्तरों ने वर्णित किया है, ऐसा करने के लिए अभी भी ऐसा लगता है कि आप सीधे गुणों को असाइन कर रहे हैं।


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

इसके बारे में सोचें; जब आपका स्थैतिक रूप से संकलित प्रोग्राम सफलतापूर्वक किसी भी त्रुटि के साथ संकलित नहीं होता है, तो आप जानते हैं कि यह सभी बगों से पूरी तरह से मुक्त है जो संकलक का पता लगा सकता है (हास्केल या बुध जैसी भाषाओं के मामले में, जो कि बहुत अच्छी गारंटी है, हालांकि अभी भी पूरा नहीं हुआ है; सी ++ या जावा जैसी भाषाओं का मामला ... meh)।

लेकिन पायथन में, टाइप त्रुटि केवल तभी देखी जाएगी जब इसे कभी निष्पादित किया जाता है। इसका मतलब है, भले ही आप अपने कार्यक्रम में पूर्ण स्थिर प्रकार प्रवर्तन हर जगह प्राप्त कर सकें, आपको वास्तव में 100% कोड कवरेज के साथ परीक्षण सूट निष्पादित करने की आवश्यकता है ताकि वास्तव में पता चल सके कि आपका प्रोग्राम प्रकार की त्रुटियों से मुक्त है। लेकिन अगर आपने नियमित रूप से पूर्ण कवरेज के साथ परीक्षण निष्पादित किए हैं तो जानते हैं यदि आपके पास कोई प्रकार की त्रुटियां हैं, यहां तक ​​कि प्रकारों को लागू करने के प्रयास किए बिना भी! तो लाभ वास्तव में वास्तव में मेरे लिए लायक नहीं लगता है। आप अपनी कमजोरियों में से एक में एक ट्राइफल से अधिक प्राप्त किए बिना पाइथन की ताकत (लचीलापन) फेंक रहे हैं (स्थिर त्रुटि का पता लगाने)।

+0

आमतौर पर, डेवलपर के लिए टाइप अधिक मार्गदर्शिका होती है वे वास्तव में एक वस्तु का उपयोग करते हैं। यह अच्छे प्रकार को पारित करने में मदद करता है और देव को सूचित करता है कि ऑब्जेक्ट की विधि का सही तरीके से उपयोग कैसे करें। इसके अलावा, "टाइप एरर, फॉनक्शन एक्स को पास किया गया गलत मान" के साथ डीबग करना बहुत आसान है, "टाइप इंट नहीं है 'एपेंड' फ़ंक्शन" के बजाय "सूची 'की आवश्यकता है। जब आपको वास्तव में सूची की आवश्यकता होती है तो आप अपने फ़ंक्शन में एक पूर्णांक क्यों स्वीकार करेंगे? – Nico

+1

@ निको यह वास्तव में एक सूची की आवश्यकता होने पर एक पूर्णांक को स्वीकार करने के बारे में नहीं है। यह कुछ भी स्वीकार करने के बारे में है (उपयुक्त रूप से अच्छी तरह से व्यवहार किया गया) 'संलग्न' विधि। जब आपने लिखा हुआ कोड पूरी तरह से अच्छा काम करता है तो आप मेरी 'रस्सी' कक्षा (तारों की विशेष सूची) को क्यों अस्वीकार कर देंगे? एक वास्तविक दुनिया प्रोजेक्ट में मेरे पास वास्तव में एक मॉड्यूल है जिसमें 5-भिन्न भिन्नताएं हैं जैसे कि (ऑब्जेक्ट' को छोड़कर) उनमें से सभी को सामान्य नहीं है।यदि वे सभी लाइब्रेरी कोड मैं 'dict' के स्पष्ट रूप से आवश्यक उदाहरणों का उपयोग कर रहा हूं तो वे बेकार होंगे। – Ben

+0

"और यह किसी भी को चरम को असाइन करने के बजाए अपने सेटटर का उपयोग करने के लिए मजबूर करना बहुत असंभव है" वास्तव में - यह सच नहीं है पाइथन। यदि आप वर्णनकर्ताओं का उपयोग करते हैं (जिन्हें 'संपत्ति' सहायक कॉलर के साथ आसानी से पूरा किया जाता है), तो सेटर फ़ंक्शन का उपयोग न करने के लिए इसे कुछ बदसूरत हैकिंग की आवश्यकता होगी। – jsbueno

5

आम तौर पर, @yak ने अपनी टिप्पणी में उल्लेख किए गए कारणों के लिए यह एक अच्छा विचार नहीं है। आप मूल रूप से ऐसे वैध तर्कों की आपूर्ति करने से उपयोगकर्ता को रोक रहे हैं जिनके पास सही गुण/व्यवहार है, लेकिन आप विरासत के पेड़ में नहीं हैं, जिनमें आप हार्ड-कोड किए गए हैं।

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

अवहेलना __setattr__

यह विधि केवल एक (बहुत) गुण है कि आप करने के लिए ऐसा करने की छोटी संख्या के लिए सुविधाजनक हो जाएगा। __setattr__ विधि तब होती है जब आप नियमित विशेषता निर्दिष्ट करने के लिए डॉट नोटेशन का उपयोग करते हैं। उदाहरण के लिए,

class A: 
    def __init__(self, a0): 
     self.a = a0 

अब हम A().a = 32 करते हैं, यह A().__setattr__('a', 32)under the hood कहेंगे। वास्तव में, self.a = a0__init__ में self.__setattr__ का भी उपयोग करता है। आप प्रकार की जांच लागू करने के लिए इस का उपयोग कर सकते हैं:

class A: 
    def __init__(self, a0): 
     self.a = a0 
    def __setattr__(self, name, value): 
     if name == 'a' and not isinstance(value, int): 
      raise TypeError('A.a must be an int') 
     super().__setattr__(name, value) 

इस विधि का नुकसान आप (किसी निश्चित प्रकार के लिए कई नामों की जाँच करने के लिए या if name in ...) प्रत्येक प्रकार आप जाँच करना चाहते हैं के लिए एक अलग if name == ... है करना है । इसका फायदा यह है कि उपयोगकर्ता को टाइप चेक को रोकने के लिए लगभग असंभव बनाने का यह सबसे सरल तरीका है।

(आमतौर पर एक एनोटेशन का उपयोग करके) एक संपत्ति

गुण ऑब्जेक्ट की जानकारी देता वस्तु के साथ अपने सामान्य विशेषता की जगह हो। वर्णनकर्ताओं के पास __get__ और __set__ विधियां हो सकती हैं जो अंतर्निहित विशेषता का उपयोग कैसे करती हैं अनुकूलित करें। यह if शाखा __setattr__ में ले जाने और इसे उस विधि में डालने जैसा है जो केवल उस विशेषता के लिए चलाएगा। ही बात कर के

class A: 
    def __init__(self, a0): 
     self.a = a0 
    @property 
    def a(self): 
     return self._a 
    @a.setter 
    def a(self, value): 
     if not ininstance(value, int): 
      raise TypeError('A.a must be an int') 
     self._a = value 

एक थोड़ा अलग तरीके से @ jsbueno के जवाब में पाया जा सकता: यहाँ एक उदाहरण है।

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

एक सच सेटर केवल डिस्क्रिप्टर

यह समाधान शायद सबसे मजबूत समग्र है बनाएँ। यह ऊपर उल्लिखित प्रश्न के लिए accepted answer में सुझाया गया है। असल में, एक संपत्ति है, जो तामझाम और उपयुक्तता कि आप में से छुटकारा नहीं मिल रहा का एक समूह है उपयोग करने के बजाय, अपने खुद के वर्णनकर्ता एनोटेशन बना सकते हैं और उपयोग करने वाले सभी गुण है कि प्रकार की जाँच की आवश्यकता के लिए:

class SetterProperty: 
    def __init__(self, func, doc=None): 
     self.func = func 
     self.__doc__ = doc if doc is not None else func.__doc__ 
    def __set__(self, obj, value): 
     return self.func(obj, value) 

class A: 
    def __init__(self, a0): 
     self.a = a0 
    @SetterProperty 
    def a(self, value): 
     if not ininstance(value, int): 
      raise TypeError('A.a must be an int') 
     self.__dict__['a'] = value 

सेटर stashes वास्तविक मूल्य सीधे __dict__ में उदाहरण के लिए अनिश्चित काल तक खुद को पुनः प्राप्त करने से बचने के लिए। इससे स्पष्ट गेटर की आपूर्ति किए बिना विशेषता का मूल्य प्राप्त करना संभव हो जाता है। चूंकि वर्णनकर्ता a में __get__ विधि नहीं है, इसलिए खोज तब तक जारी रहेगी जब तक कि यह __dict__ में विशेषता नहीं पाती। यह सुनिश्चित करता है कि सभी सेट डिस्क्रिप्टर/सेटर के माध्यम से जाते हैं जबकि विशेषता मान तक सीधे पहुंच की अनुमति मिलती है।

आप गुण इस तरह एक जांच की आवश्यकता है कि की एक बड़ी संख्या है, तो आप वर्णनकर्ता के __set__ विधि में लाइन self.__dict__['a'] = value स्थानांतरित कर सकते हैं:

class ValidatedSetterProperty: 
    def __init__(self, func, name=None, doc=None): 
     self.func = func 
     self.__name__ = name if name is not None else func.__name__ 
     self.__doc__ = doc if doc is not None else func.__doc__ 
    def __set__(self, obj, value): 
     ret = self.func(obj, value) 
     obj.__dict__[self.__name__] = value 

class A: 
    def __init__(self, a0): 
     self.a = a0 
    @ValidatedSetterProperty 
    def a(self, value): 
     if not ininstance(value, int): 
      raise TypeError('A.a must be an int') 

अद्यतन

Python3.6 करता है आपके लिए लगभग बॉक्स के बाहर: https://docs.python.org/3.6/whatsnew/3.6.html#pep-487-descriptor-protocol-enhancements

टीएल; डीआर

टाइप-चेकिंग की आवश्यकता वाले बहुत कम गुणों के लिए, सीधे __setattr__ ओवरराइड करें। बड़ी संख्या में विशेषताओं के लिए, उपरोक्त दिखाए गए सेटटर-केवल वर्णनकर्ता का उपयोग करें। इस प्रकार के आवेदन के लिए सीधे गुणों का उपयोग करने से हल होने की तुलना में अधिक समस्याएं उत्पन्न होती हैं।

1

मुझे पता है कि इस चर्चा को सुलझा लिया गया है, लेकिन पाइथन संरचना मॉड्यूल शो का उपयोग करने के लिए एक बहुत ही सरल समाधान है। इससे पहले कि आप इसे मान निर्दिष्ट करने से पहले अपने डेटा के लिए एक कंटेनर बनाने की आवश्यकता होगी, लेकिन यह डेटा प्रकार स्थिर रखने में बहुत प्रभावी है।https://pypi.python.org/pypi/structures

1

पिछली पोस्टों और कुछ सोचों के लिए धन्यवाद, मेरा मानना ​​है कि मैंने क्लास एट्रिब्यूट को विशिष्ट प्रकार के रूप में प्रतिबंधित करने के तरीके के बारे में अधिक उपयोगकर्ता-अनुकूल तरीका निकाला है।

def ensure_type(value, types): 
    if isinstance(value, types): 
     return value 
    else: 
     raise TypeError('Value {value} is {value_type}, but should be {types}!'.format(
      value=value, value_type=type(value), types=types)) 

तो हम बस का उपयोग करें और सेटर के माध्यम से हमारे कक्षाओं में लागू:

सबसे पहले हम एक समारोह है, जो सार्वभौमिक प्रकार के लिए परीक्षण पैदा करते हैं। मुझे लगता है कि यह अपेक्षाकृत सरल है और DRY का पालन करें, खासकर जब आप इसे अपनी पूरी परियोजना को खिलाने के लिए एक अलग मॉड्यूल में निर्यात करते हैं। नीचे उदाहरण देखें:

class Product: 
    def __init__(self, name, quantity): 
     self.name = name 
     self.quantity = quantity 

    @property 
    def name(self): 
     return self.name 

    @name.setter 
    def name(self, value): 
     self.__dict__['name'] = ensure_type(value, str) 

    @property 
    def quantity(self): 
     return self.quantity 

    @quantity.setter 
    def quantity(self, value): 
     self.__dict__['quantity'] = ensure_type(value, int) 

परीक्षण उचित परिणाम उत्पन्न करते हैं। पहले परीक्षण देखें:

if __name__ == '__main__': 
    from traceback import format_exc 

    try: 
     p1 = Product(667, 5) 
    except TypeError as err: 
     print(format_exc(1)) 

    try: 
     p2 = Product('Knight who say...', '5') 
    except TypeError as err: 
     print(format_exc(1)) 

    p1 = Product('SPAM', 2) 
    p2 = Product('...and Love', 7) 
    print('Objects p1 and p2 created successfully!') 

    try: 
     p1.name = -191581 
    except TypeError as err: 
     print(format_exc(1)) 

    try: 
     p2.quantity = 'EGGS' 
    except TypeError as err: 
     print(format_exc(1)) 

और परीक्षण परिणाम:

Traceback (most recent call last): 
    File "/Users/BadPhoenix/Desktop/Coding/Coders-Lab/Week-2/WAR_PYT_S_05_OOP/2_Praca_domowa/day-1/stackoverflow.py", line 35, in <module> 
    p1 = Product(667, 5) 
TypeError: Value 667 is <class 'int'>, but should be <class 'str'>! 

Traceback (most recent call last): 
    File "/Users/BadPhoenix/Desktop/Coding/Coders-Lab/Week-2/WAR_PYT_S_05_OOP/2_Praca_domowa/day-1/stackoverflow.py", line 40, in <module> 
    p2 = Product('Knights who say...', '5') 
TypeError: Value 5 is <class 'str'>, but should be <class 'int'>! 

Objects p1 and p2 created successfully! 

Traceback (most recent call last): 
    File "/Users/BadPhoenix/Desktop/Coding/Coders-Lab/Week-2/WAR_PYT_S_05_OOP/2_Praca_domowa/day-1/stackoverflow.py", line 49, in <module> 
    p1.name = -191581 
TypeError: Value -191581 is <class 'int'>, but should be <class 'str'>! 

Traceback (most recent call last): 
    File "/Users/BadPhoenix/Desktop/Coding/Coders-Lab/Week-2/WAR_PYT_S_05_OOP/2_Praca_domowa/day-1/stackoverflow.py", line 54, in <module> 
    p2.quantity = 'EGGS' 
TypeError: Value EGGS is <class 'str'>, but should be <class 'int'>! 
0

अजगर 3.5 के बाद से, आप type-hints उपयोग कर सकते हैं दर्शाता है कि एक वर्ग विशेषता एक विशेष प्रकार का होना चाहिए। फिर, आप अपने निरंतर एकीकरण प्रक्रिया के हिस्से के रूप में MyPy जैसे कुछ शामिल कर सकते हैं ताकि सभी प्रकार के अनुबंधों का सम्मान किया जा सके।

उदाहरण के लिए

, निम्नलिखित अजगर स्क्रिप्ट के लिए:

6: error: Incompatible types in assignment (expression has type "str", variable has type "int") 

यदि आप चाहते हैं प्रकार के क्रम में लागू किए जाने, आप enforce पैकेज इस्तेमाल कर सकते हैं:

class Foo: 
    x: int 
    y: int 

foo = Foo() 
foo.x = "hello" 

MyPy निम्न त्रुटि देना होगा । रीडमे से:

>>> import enforce 
>>> 
>>> @enforce.runtime_validation 
... def foo(text: str) -> None: 
...  print(text) 
>>> 
>>> foo('Hello World') 
Hello World 
>>> 
>>> foo(5) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/william/.local/lib/python3.5/site-packages/enforce/decorators.py", line 106, in universal 
    _args, _kwargs = enforcer.validate_inputs(parameters) 
    File "/home/william/.local/lib/python3.5/site-packages/enforce/enforcers.py", line 69, in validate_inputs 
    raise RuntimeTypeError(exception_text) 
enforce.exceptions.RuntimeTypeError: 
    The following runtime type errors were encountered: 
     Argument 'text' was not of type <class 'str'>. Actual type was <class 'int'>. 
संबंधित मुद्दे