पायथन मुखर के लिए सबसे अच्छा अभ्यास


483
  1. क्या assertकेवल डिबगिंग उद्देश्यों के लिए उपयोग करने के बजाय मानक कोड के भाग के रूप में उपयोग करने के साथ कोई प्रदर्शन या कोड रखरखाव समस्या है?

    है

    assert x >= 0, 'x is less than zero'

    से बेहतर या बुरा

    if x < 0:
        raise Exception, 'x is less than zero'
  2. इसके अलावा, कोई भी व्यापार नियम निर्धारित करने का कोई तरीका है if x < 0 raise errorजो हमेशा बिना जांचे-परखे try/except/finally, यदि किसी भी समय पूरे कोड xमें 0 से कम त्रुटि हुई है, जैसे कि आप assert x < 0किसी फ़ंक्शन के प्रारंभ में, फ़ंक्शन के भीतर कहीं भी सेट होते हैं जहां xकम हो जाता है तो 0 अपवाद उठाया जाता है?



29
-O और -o python पैरामीटर आपके दावे को दूर कर देंगे। यह आपकी सोच को आगे बढ़ा सकता है कि यह किसके लिए अच्छा है।
पीटर लाडा

4
थॉमस ज़िलिंस्की का लिंक टूट गया, अब यह है: mail.python.org/pipermail/python-list/2013-Nvent/660568.html । मुझे पूरा यकीन है कि पिपरमेल में एक अस्थिर आईडी फ़ंक्शन होता है, मुझे उसी इरादे से उसी url की ओर इशारा करते हुए उसी पिपरमेल के अंदर से अन्य लिंक मिले।
quodlibetor

3
में मामला mail.python.org/pipermail/python-list/2013-November/660568.html फिर से चलता है, उस पर संग्रहीत है archive.is/5GfiG । पोस्ट का शीर्षक है "जब मुखर का उपयोग करना है" और पायथन के लिए सर्वोत्तम प्रथाओं पर एक उत्कृष्ट पोस्ट (वास्तव में एक लेख) है assert
क्लेक

जवाबों:


144

जब पूरे फ़ंक्शन में x शून्य से कम हो जाता है, तो स्वचालित रूप से एक त्रुटि फेंकने में सक्षम होने के लिए। आप क्लास डिस्क्रिप्टर का उपयोग कर सकते हैं । यहाँ एक उदाहरण है:

class LessThanZeroException(Exception):
    pass

class variable(object):
    def __init__(self, value=0):
        self.__x = value

    def __set__(self, obj, value):
        if value < 0:
            raise LessThanZeroException('x is less than zero')

        self.__x  = value

    def __get__(self, obj, objType):
        return self.__x

class MyClass(object):
    x = variable()

>>> m = MyClass()
>>> m.x = 10
>>> m.x -= 20
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "my.py", line 7, in __set__
    raise LessThanZeroException('x is less than zero')
LessThanZeroException: x is less than zero

10
हालाँकि संपत्तियों को वर्णनकर्ताओं के रूप में लागू किया जाता है, मैं इसे उनके उपयोग का उदाहरण नहीं कहूंगा। यह खुद में और खुद के गुणों का एक उदाहरण है: docs.python.org/library/functions.html#property
जेसन बेकर

3
गुणों को x सेट करते समय MyClass के भीतर उपयोग किया जाना चाहिए। यह समाधान बहुत सामान्य है।

112
बहुत अच्छा जवाब, यह पसंद है, लेकिन सवाल के साथ कुछ नहीं करना है ... क्या हम देवेन या जॉन मेई के जवाब को वैध प्रतिक्रिया के रूप में चिह्नित नहीं कर सकते हैं?
वाजेक हर्मेज़

4
यह प्रश्न के शीर्षक का उत्तर नहीं देता है। इसके अलावा, यह पायथन की वर्ग संपत्ति विशेषता का एक खराब विकल्प है।
कयामत

10
@VajkHermecz: वास्तव में, यदि आप प्रश्न को फिर से पढ़ते हैं, तो यह एक में दो प्रश्न हैं। केवल शीर्षक देख रहे लोग केवल पहले प्रश्न से परिचित हैं, जिसका उत्तर इस उत्तर में नहीं है। इस उत्तर में वास्तव में दूसरे प्रश्न का उत्तर होता है।
आर्टऑफवर्फ

742

ऐसी परिस्थितियों का परीक्षण करने के लिए अभ्रक का उपयोग किया जाना चाहिए जो कभी नहीं होना चाहिए । उद्देश्य एक भ्रष्ट कार्यक्रम राज्य के मामले में जल्दी दुर्घटना करना है।

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


उदाहरण के लिए, यदि आप किसी कॉन्फ़िगरेशन फ़ाइल से पढ़ने के लिए कोई फ़ंक्शन लिख रहे हैं, तो फ़ाइल में dictअनुचित स्वरूपण को बढ़ा देना चाहिए ConfigurationSyntaxError, जबकि आप यह कर सकते हैं assertकि आप लौटने वाले नहीं हैं None


आपके उदाहरण में, यदि xउपयोगकर्ता इंटरफ़ेस या बाहरी स्रोत से कोई मान सेट है , तो एक अपवाद सबसे अच्छा है।

यदि xकेवल उसी प्रोग्राम में आपके स्वयं के कोड द्वारा सेट किया गया है, तो एक जोर के साथ जाएं।


126
यह जोर लगाने का सही तरीका है। उन्हें कार्यक्रम प्रवाह को नियंत्रित करने के लिए उपयोग नहीं किया जाना चाहिए।
ठाणे ब्रिम्हल

41
+1 अंतिम अनुच्छेद के लिए - हालांकि आप चाहिए स्पष्ट रूप से उल्लेख है कि assertएक अंतर्निहित होता है if __debug__और किया जा सकता है अनुकूलित दूर - के रूप में जॉन मी के जवाब राज्यों
टोबियास Kienzler

3
अपने उत्तर के बारे में सोचने के बाद मुझे लगता है कि आप शायद ऐसी स्थिति का मतलब नहीं है जो एक नियम के रूप में कभी भी नहीं होना चाहिए , बल्कि इसका उद्देश्य एक भ्रष्ट कार्यक्रम राज्य के मामले में जल्दी दुर्घटना करना है जो आमतौर पर एक ऐसी स्थिति से मेल खाता है जिसकी आपको उम्मीद नहीं है कभी होने के लिए
बेंटले

10
मुखर केवल किसी भी ज्ञात वसूली के साथ समस्याओं को पकड़ने के लिए इस्तेमाल किया जाना चाहिए; लगभग हमेशा कोड बग (खराब इनपुट नहीं)। जब एक जोर दिया जाता है, तो इसका मतलब यह होना चाहिए कि कार्यक्रम एक ऐसी स्थिति में है जिसे जारी रखना खतरनाक हो सकता है, क्योंकि यह नेटवर्क से बात करना या डिस्क पर लिखना शुरू कर सकता है। मजबूत कोड खराब स्थिति (या दुर्भावनापूर्ण) इनपुट के कारण वैध स्थिति से 'परमाणु' तक चलता है। हर धागे के शीर्ष स्तर में एक बाधा बाधा होनी चाहिए। बाहरी दुनिया से इनपुट का उपभोग करने वाले दोष बाधाएं आम तौर पर बाधा (जबकि / कोशिश), रोलबैक / त्रुटि पर लॉग के केवल एक पुनरावृत्ति के लिए विफल होती हैं।
रोब

10
"ऐसी परिस्थितियों का परीक्षण करने के लिए अभ्रक का उपयोग किया जाना चाहिए जो कभी नहीं होना चाहिए।" हाँ। और दूसरे "चाहिए" का अर्थ है: यदि ऐसा होता है, तो प्रोग्राम कोड गलत है।
लुत्ज प्रेचल

362

संकलन के अनुकूलित होने पर "मुखर" बयान हटा दिए जाते हैं । तो, हां, प्रदर्शन और कार्यात्मक अंतर दोनों हैं।

जब वर्तमान समय में अनुकूलन का अनुरोध किया जाता है, तो वर्तमान कोड जनरेटर किसी मुखर कथन के लिए कोई कोड नहीं बनाता है। - पायथन 2 डॉक्स पायथन 3 डॉक्स

यदि आप assertएप्लिकेशन कार्यक्षमता को लागू करने के लिए उपयोग करते हैं, तो उत्पादन के लिए तैनाती का अनुकूलन करें, तो आप "लेकिन यह-यह-काम-इन-देव" दोषों से ग्रस्त हो जाएगा।

PYTHONOPTIMIZE और -O -OO देखें


26
वाह! सुपर महत्वपूर्ण नोट है! मैं कुछ चीजों की जांच करने के लिए जोर लगाने की योजना बना रहा था, जो कभी भी विफल नहीं होनी चाहिए, जिनकी विफलता यह दर्शाती है कि कोई व्यक्ति मेरे डेटा में बहुत सावधानी से हेरफेर कर रहा था जो वे डेटा तक पहुंच प्राप्त करने के प्रयास में भेज रहे थे जिसकी उन्हें पहुंच नहीं होनी चाहिए। यह काम नहीं करेगा, लेकिन मैं तेजी से अपने प्रयास को एक जोर के साथ बंद करना चाहता हूं, ताकि उत्पादन में दूर अनुकूलित उद्देश्य को हरा सके। मुझे लगता है कि मैं सिर्फ raiseएक Exceptionबदले में हूँ । ओह - मैंने अभी SuspiciousOperation Exceptionउपवर्गों के साथ एक उपयुक्त नाम खोजा है Django! उत्तम!
ArtOfWarfare

वैसे @ArtOfWarfare अगर आप banditअपने कोड पर चलते हैं , तो यह आपको इसके बारे में चेतावनी देगा।
नागदेव

132

के चार उद्देश्य assert

मान लें कि आप चार सहयोगियों ऐलिस, बर्नड, कार्ल और डैफने के साथ 200,000 लाइनों के कोड पर काम करते हैं। वे आपका कोड कहते हैं, आप उनका कोड कहते हैं।

तो assertहै चार भूमिकाओं :

  1. ऐलिस, बर्न, कार्ल और डैफने को सूचित करें कि आपका कोड क्या उम्मीद करता है।
    मान लें कि आपके पास एक तरीका है जो ट्यूपल्स की एक सूची बनाता है और प्रोग्राम लॉजिक टूट सकता है यदि वे ट्यूपल्स अपरिवर्तनीय नहीं हैं:

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))

    यह दस्तावेज़ीकरण में समकक्ष जानकारी की तुलना में अधिक भरोसेमंद है और बनाए रखने के लिए बहुत आसान है।

  2. कंप्यूटर को सूचित करें कि आपका कोड क्या उम्मीद करता है।
    assertआपके कोड के कॉल करने वालों से उचित व्यवहार लागू करता है। यदि आपका कोड एलिस का कॉल करता है और बर्नड का कोड आपको कॉल करता है, तो इसके बिना assert, यदि प्रोग्राम एलिस कोड में दुर्घटनाग्रस्त हो जाता है, तो बर्नड यह मान सकता है कि यह ऐलिस की गलती थी, ऐलिस जांच करता है और यह मान सकता है कि यह आपकी गलती थी, आप जांच करें और बताएं कि यह वास्तव में था। उसके। बहुत काम छूट गया।
    मुखरता से, जो कोई भी कॉल गलत होता है, वे जल्दी से यह देख पाएंगे कि यह उनकी गलती थी, आपकी नहीं। ऐलिस, बर्नड, और आप सभी लाभान्वित होते हैं। समय की अपार मात्रा बचाता है।

  3. अपने कोड के पाठकों को सूचित करें (अपने आप सहित) कुछ बिंदु पर आपके कोड ने क्या हासिल किया है।
    मान लें कि आपके पास प्रविष्टियों की एक सूची है और उनमें से प्रत्येक साफ हो सकता है (जो अच्छा है) या यह smorsh, trale, gullup, या twinkled हो सकता है (जो सभी स्वीकार्य नहीं हैं)। यदि यह बदबूदार है, तो इसे अनमॉर्स्ड होना चाहिए; अगर यह कमज़ोर है तो इसे अवश्य ही छद्म होना चाहिए; अगर यह गुपचुप है, तो इसे ट्रॉट किया जाना चाहिए (और संभवतः संभवतः, भी); यदि यह ट्विंकल है तो इसे गुरुवार को छोड़कर फिर से ट्विंकल किया जाना चाहिए। आपको यह विचार मिलता है: यह जटिल सामान है। लेकिन अंतिम परिणाम यह है (या होना चाहिए) कि सभी प्रविष्टियां साफ हैं। राइट थिंग (TM) करने के लिए अपने सफाई पाश के प्रभाव को संक्षेप में प्रस्तुत करना है

    assert(all(entry.isClean() for entry in mylist))

    यह कथन हर किसी को समझने की कोशिश करने के लिए सिरदर्द को बचाता है कि वास्तव में यह क्या है कि अद्भुत लूप प्राप्त कर रहा है। और इन लोगों में से सबसे अधिक संभावना अपने आप होगी।

  4. कंप्यूटर को सूचित करें कि आपके कोड ने किसी बिंदु पर क्या हासिल किया है।
    क्या आपको कभी प्रविष्टि को गति देने के लिए भूल जाना चाहिए, जो कि टटोलने के बाद चाहिए, इससे assertआपका दिन बचेगा और इससे बचें कि आपका कोड प्रिय डैफने के बहुत बाद में टूट जाता है।

मेरे दिमाग में, assertप्रलेखन के दो उद्देश्य (1 और 3) और सुरक्षा (2 और 4) समान रूप से मूल्यवान हैं। कंप्यूटर को सूचित करने की तुलना
में लोगों को सूचित करना और भी अधिक मूल्यवान हो सकता है क्योंकि यह बहुत गलतियों assertको पकड़ने के उद्देश्य (1 मामले में) और किसी भी मामले में बहुत बाद की गलतियों को रोक सकता है ।


34
5. एसेन्सरटेंस () PyCharm (अजगर IDE) को चर के प्रकार को जानने में मदद करता है, इसका उपयोग स्वतः पूर्ण के लिए किया जाता है।
Cjkjvfnby

1
वर्तमान निष्पादन समय में जो सत्य है, उसके लिए स्व-दस्तावेज़ कोड मान्यताओं को सम्मिलित करता है। यह एक धारणा टिप्पणी है, जो जाँच की जाती है।
पायज

9
2 और 4 के बारे में: आपको बहुत सावधान रहना चाहिए कि आपके मुखर बहुत सख्त नहीं हैं। खुद को जोर देकर कहें कि आपके प्रोग्राम को अधिक सामान्य सेटिंग में उपयोग करने के लिए केवल एक चीज हो सकती है। विशेष रूप से मुखर प्रकार अजगर के डक-टाइपिंग के खिलाफ जाता है।
zwirbeltier

9
@Cjkjvfnby इस ब्लॉग प्रविष्टि में वर्णित आइंस्टीन () के अति प्रयोग के बारे में सावधान रहें: " आइंस्टीन () हानिकारक माना जाता है "। अब आप Pycharm में प्रकार निर्दिष्ट करने के लिए docstrings का उपयोग कर सकते हैं ।
बाइनरीसबस्ट्रेट

2
अनुबंध सुनिश्चित करने के एक तरीके में जोर का उपयोग करना। अनुबंध द्वारा डिजाइन के बारे में अधिक जानकारी en.wikipedia.org/wiki/Design_by_contract
Leszek Zarna

22

अन्य उत्तरों के अलावा, एसर्स खुद अपवादों को फेंकते हैं, लेकिन केवल जोर देते हैं। उपयोगितावादी दृष्टिकोण से, जब आप ठीक-ठाक अनाज नियंत्रण की आवश्यकता पर जोर देते हैं, तो इसके लिए उपयुक्त नहीं हैं।


3
सही। यह मूर्खतापूर्ण प्रतीत होता है कि कॉलर में अपवाद त्रुटि को पकड़ने के लिए।
रफ़ी खाचदौरीयन

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

आपके उत्तर को पढ़ा जा सकता है जैसे कि आप पकड़ना चाहते हैं AssertionErrors, जब आप इसके साथ मोटे-मोटे होते हैं। वास्तव में, आपको उन्हें पकड़ना नहीं चाहिए।
टॉमस गैंडर

19

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

class XLessThanZeroException(Exception):
    pass

def CheckX(x):
    if x < 0:
        raise XLessThanZeroException()

def foo(x):
    CheckX(x)
    #do stuff here

एक और समस्या यह है कि सामान्य स्थिति-जाँच के लिए एस्टर का उपयोग करना यह है कि -O फ़्लैग का उपयोग करके डीबगिंग एसेर्स को अक्षम करना मुश्किल हो जाता है।


24
आप किसी त्रुटि संदेश को दावे के लिए जोड़ सकते हैं। यह दूसरा पैरामीटर है। यह इसे वर्णनात्मक बना देगा।
रफ़ी खाचदौरियन

10

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

# I solemnly swear that here I will tell the truth, the whole truth, 
# and nothing but the truth, under pains and penalties of perjury, so help me FSM
assert answer == 42

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


8

जैसा कि पहले कहा गया है, जब आपके कोड कभी भी एक बिंदु तक नहीं पहुंचते हैं, तो इसका मतलब होना चाहिए कि वहां एक बग है। संभवतः सबसे उपयोगी कारण जो मैं देख सकता हूं कि एक जोर का उपयोग करना एक अपरिवर्तनीय / पूर्व / पोस्टकंडिशन है। ये कुछ ऐसे हैं जो लूप या फ़ंक्शन के प्रत्येक पुनरावृत्ति के प्रारंभ या अंत में सही होना चाहिए।

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

def SumToN(n):
    if n <= 0:
        raise ValueError, "N must be greater than or equal to 0"
    else:
        return RecursiveSum(n)

def RecursiveSum(n):
    #precondition: n >= 0
    assert(n >= 0)
    if n == 0:
        return 0
    return RecursiveSum(n - 1) + n
    #postcondition: returned sum of 1 to n

इन लूप आक्रमणकारियों को अक्सर एक दावे के साथ दर्शाया जा सकता है।


2
यह डेकोरेटर्स (@precondition and @postcondition) के साथ सबसे अच्छा किया जाता है
Caridorc

@Caridorc उस का ठोस लाभ क्या है?
चील टेन ब्रिंच

@ChieltenBrinke स्व दस्तावेज कोड के बजाय #precondition: n >= 0 और एक जोर से, वह सिर्फ लिख सकता है@precondition(lambda n: n >= 0)
Caridorc

@Caridorc तो उन निर्मित सज्जाकार हैं? और उस से एक दस्तावेज़ कैसे उत्पन्न होता है?
चिले दस ब्रिंक

@ChieltenBrinke में निर्मित नहीं लेकिन आसान लागू करने के लिए stackoverflow.com/questions/12151182/... । प्रलेखन के लिए बस __doc__एक अतिरिक्त स्ट्रिंग देकर विशेषता को
थपथपाएं

4

क्या कोई प्रदर्शन मुद्दा है?

  • कृपया याद रखें "इससे पहले कि आप इसे तेजी से काम करने से पहले काम करें"
    किसी भी कार्यक्रम का बहुत कम प्रतिशत आमतौर पर इसकी गति के लिए प्रासंगिक होता है। आप हमेशा किक आउट या सरल कर सकते हैंassert कभी भी प्रदर्शन की समस्या साबित होते हैं, तो - और उनमें से अधिकांश कभी नहीं करेंगे।

  • व्यावहारिक रहें :
    मान लें कि आपके पास एक ऐसी विधि है जो ट्यूपल्स की गैर-रिक्त सूची को संसाधित करती है और यदि उन ट्यूपल्स अपरिवर्तनीय नहीं हैं तो प्रोग्राम लॉजिक टूट जाएगा। आपको लिखना चाहिए:

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))

    यह संभवत: ठीक है यदि आपकी सूचियाँ दस प्रविष्टियाँ लंबी होती हैं, लेकिन यह एक समस्या हो सकती है यदि उनके पास एक लाख प्रविष्टियाँ हों। लेकिन इस मूल्यवान जाँच को पूरी तरह से त्यागने के बजाय आप बस इसे डाउनग्रेड कर सकते हैं

    def mymethod(listOfTuples):
        assert(type(listOfTuples[0])==tuple)  # in fact _all_ must be tuples!

    जो सस्ता है, लेकिन वैसे भी वास्तविक कार्यक्रम की अधिकांश त्रुटियों को पकड़ लेगा ।


2
होना चाहिए assert(len(listOfTuples)==0 or type(listOfTyples[0])==tuple)
osa

नहीं, ऐसा नहीं होना चाहिए। यह एक बहुत ही कमजोर परीक्षण होगा, क्योंकि यह अब 'गैर-खाली' संपत्ति की जांच नहीं करता है, जिसे दूसरा परखता है। (पहले ऐसा नहीं है, हालांकि यह होना चाहिए।)
लुट्ज़ प्रीचेल

1
दूसरा मुखर गैर-रिक्त संपत्ति की स्पष्ट रूप से जांच नहीं करता है; यह एक साइड इफेक्ट के अधिक है। यदि सूची खाली होने के कारण इसे अपवाद बनाना होता है, तो कोड के साथ काम करने वाला व्यक्ति (किसी और या लेखक, इसे लिखने के एक साल बाद) इसे घूरता है, यह पता लगाने की कोशिश कर रहा है कि क्या वास्तव में जोर पकड़ने का मतलब था रिक्त सूची की स्थिति, या यदि वह स्वयं में त्रुटि है। इसके अलावा, मैं यह नहीं देखता कि खाली मामले की जांच कैसे "बहुत कमजोर" है, जबकि केवल पहला तत्व "97% सही" है।
osa

3

खैर, यह एक खुला प्रश्न है, और मेरे पास दो पहलू हैं जिन पर मैं स्पर्श करना चाहता हूं: जब कुछ जोड़ना हो और त्रुटि संदेश कैसे लिखना है।

उद्देश्य

इसे एक शुरुआत करने के लिए समझाने के लिए - कथन ऐसे कथन हैं जो त्रुटियों को बढ़ा सकते हैं, लेकिन आप उन्हें पकड़ नहीं पाएंगे। और उन्हें आम तौर पर नहीं उठाया जाना चाहिए, लेकिन वास्तविक जीवन में वे कभी-कभी उठते हैं। और यह एक गंभीर स्थिति है, जिसे कोड से पुनर्प्राप्त नहीं किया जा सकता है, जिसे हम 'घातक त्रुटि' कहते हैं।

इसके बाद, यह 'डिबगिंग उद्देश्यों' के लिए है, जो सही होने के साथ-साथ बहुत खारिज कर देता है। मुझे 'घोषित करने वाले आक्रमणकारी, जिन्हें कभी भी उल्लंघन नहीं करना चाहिए' बेहतर लगता है, हालांकि यह अलग-अलग शुरुआती पर अलग तरह से काम करता है ... कुछ 'बस इसे प्राप्त करते हैं', और अन्य या तो इसके लिए कोई उपयोग नहीं करते हैं, या सामान्य अपवादों को प्रतिस्थापित करते हैं, या यहां तक ​​कि इसके साथ नियंत्रण प्रवाह।

अंदाज

पायथन में, assertएक बयान है, एक फ़ंक्शन नहीं है! (याद assert(False, 'is true')नहीं होगा, लेकिन उठो, रास्ते से बाहर:

वैकल्पिक 'त्रुटि संदेश' लिखने के लिए कब और कैसे?

यह एक यूनिट टेस्टिंग फ्रेमवर्क पर लागू होता है, जिसमें अक्सर कई दावे करने के लिए समर्पित तरीके होते हैं ( assertTrue(condition), assertFalse(condition), assertEqual(actual, expected)आदि)। वे अक्सर दावे पर टिप्पणी करने का एक तरीका भी प्रदान करते हैं।

फेंक-दूर कोड में आप त्रुटि संदेशों के बिना कर सकते थे।

कुछ मामलों में, दावे में जोड़ने के लिए कुछ भी नहीं है:

डीईएफ़ डंप (कुछ): मुखर आइंस्टीनेंस (कुछ, Dumpable) # ...

लेकिन इसके अलावा, एक संदेश अन्य प्रोग्रामर के साथ संचार के लिए उपयोगी है (जो कभी-कभी आपके कोड के इंटरैक्टिव उपयोगकर्ता होते हैं, जैसे कि इफ्थॉन / ज्यूपिटर आदि में)।

उन्हें जानकारी दें, न कि केवल आंतरिक कार्यान्वयन विवरण लीक करें।

के बजाय:

assert meaningless_identifier <= MAGIC_NUMBER_XXX, 'meaningless_identifier is greater than MAGIC_NUMBER_XXX!!!'

लिखो:

assert meaningless_identifier > MAGIC_NUMBER_XXX, 'reactor temperature above critical threshold'

या शायद यहां तक ​​कि:

assert meaningless_identifier > MAGIC_NUMBER_XXX, f'reactor temperature({meaningless_identifier }) above critical threshold ({MAGIC_NUMBER_XXX})'

मुझे पता है, मुझे पता है - यह एक स्थिर दावे के लिए मामला नहीं है, लेकिन मैं संदेश के सूचनात्मक मूल्य को इंगित करना चाहता हूं।

नकारात्मक या सकारात्मक संदेश?

यह विवादास्पद हो सकता है, लेकिन मुझे इस तरह की बातें पढ़ने के लिए दर्द होता है:

assert a == b, 'a is not equal to b'
  • ये दो विरोधाभासी बातें हैं जो प्रत्येक अभिभावक के बगल में लिखी गई हैं। इसलिए जब भी मुझे कोडबेस पर कोई प्रभाव पड़ता है, तो मैं 'वी' और 'चाहिए' जैसी अतिरिक्त क्रियाओं का उपयोग करके यह निर्दिष्ट करने के लिए धक्का देता हूं कि हम क्या चाहते हैं।

    a == b, 'a बराबर होना चाहिए b'

फिर, प्राप्त AssertionError: a must be equal to bकरना भी पठनीय है, और कथन कोड में तर्कसंगत लगता है। इसके अलावा, आप ट्रेसबैक (जो कभी-कभी उपलब्ध भी नहीं हो सकते हैं) को पढ़े बिना इसमें से कुछ निकाल सकते हैं।


1

दोनों का उपयोग assertऔर अपवादों को उठाना संचार के बारे में है।

  • डेवलपर्स पर संबोधित कोड की शुद्धता के बारे में कथन हैं : कोड में एक जोर से कोड के पाठकों को उन शर्तों के बारे में सूचित किया जाता है जिन्हें कोड के सही होने के लिए पूरा किया जाना है। रन-टाइम में विफल होने वाली एक सूचना डेवलपर्स को सूचित करती है कि कोड में एक दोष है जिसे ठीक करने की आवश्यकता है।

  • अपवाद गैर-विशिष्ट स्थितियों के बारे में संकेत हैं जो रन-टाइम पर हो सकते हैं लेकिन हाथ से कोड द्वारा हल नहीं किए जा सकते हैं, कॉलिंग कोड में संबोधित किया जा सकता है। अपवाद की घटना यह नहीं दर्शाती है कि कोड में कोई बग है।

सर्वश्रेष्ठ प्रणालियां

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

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

उपयोग करने के साथ एक प्रदर्शन [...] मुद्दा है assert

अभिकथन के मूल्यांकन में कुछ समय लगता है। हालांकि, उन्हें संकलन समय पर समाप्त किया जा सकता है। हालांकि, इसके कुछ परिणाम हैं, नीचे देखें।

उपयोग करने के साथ एक [...] कोड रखरखाव मुद्दा है assert

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


1

एक मुखर जाँच करने के लिए है -
1. वैध स्थिति,
2. वैध कथन,
3. सच्चा तर्क;
स्रोत कोड का। पूरे प्रोजेक्ट को विफल करने के बजाय यह एक अलार्म देता है कि आपके स्रोत फ़ाइल में कुछ उपयुक्त नहीं है।

उदाहरण 1 में, चूंकि चर 'str' शून्य नहीं है। इसलिए कोई भी दावा या अपवाद नहीं उठाया गया।

उदाहरण 1:

#!/usr/bin/python

str = 'hello Python!'
strNull = 'string is Null'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
hello Python!
FileName ..................... hello
FilePath ..................... C:/Python\hello.py

उदाहरण 2 में, var 'str' शून्य है। इसलिए हम उपयोगकर्ता को मुखर कथन द्वारा दोषपूर्ण कार्यक्रम से आगे जाने से बचा रहे हैं ।

उदाहरण 2:

#!/usr/bin/python

str = ''
strNull = 'NULL String'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
AssertionError: NULL String

जिस क्षण हम डिबग नहीं करना चाहते हैं और स्रोत कोड में दावे के मुद्दे का एहसास हुआ। अनुकूलन ध्वज को अक्षम करें

python -O assertStatement.py
कुछ नहीं मिलेगा प्रिंट


0

IDE जैसे PTVS, PyCharm, विंग assert isinstance()स्टेटमेंट का उपयोग कुछ अस्पष्ट वस्तुओं के लिए कोड पूरा करने में सक्षम करने के लिए किया जा सकता है।


यह प्रकार एनोटेशन या के उपयोग को पूर्वसूचक करता है typing.cast
एक्यूमेनस

-1

इसके लायक क्या है, यदि आप उस कोड के साथ काम कर रहे हैं जो assertठीक से काम करने के लिए निर्भर करता है, तो निम्नलिखित कोड जोड़कर यह सुनिश्चित करेगा कि निम्नलिखित हैं:

try:
    assert False
    raise Exception('Python assertions are not working. This tool relies on Python assertions to do its job. Possible causes are running with the "-O" flag or running a precompiled (".pyo" or ".pyc") module.')
except AssertionError:
    pass

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