अजगर में मुखरता अक्षम करें


93

मैं पायथन में दावे को कैसे अक्षम करूं?

यही कारण है कि, अगर एक असफलता विफल हो जाती है, तो मैं नहीं चाहता कि इसे फेंक दिया जाए AssertionError, लेकिन चलते रहना चाहिए।

मैं उसको कैसे करू?

जवाबों:


80

मैं पायथन में दावे को कैसे अक्षम करूं?

ऐसे कई दृष्टिकोण हैं जो किसी एकल प्रक्रिया, पर्यावरण या कोड की एकल पंक्ति को प्रभावित करते हैं।

मैं प्रत्येक को प्रदर्शित करता हूं।

पूरी प्रक्रिया के लिए

-Oध्वज (राजधानी O) का उपयोग करना एक प्रक्रिया में सभी मुखर बयानों को निष्क्रिय करता है।

उदाहरण के लिए:

$ python -Oc "assert False"

$ python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

ध्यान दें कि निष्क्रिय होने से मेरा मतलब है कि यह उस अभिव्यक्ति को भी निष्पादित नहीं करता है जो इस प्रकार है:

$ python -Oc "assert 1/0"

$ python -c "assert 1/0"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

पर्यावरण के लिए

आप इस ध्वज को सेट करने के लिए एक पर्यावरण चर का उपयोग कर सकते हैं।

यह पर्यावरण को उपयोग या विरासत में देने वाली हर प्रक्रिया को प्रभावित करेगा।

उदाहरण के लिए, विंडोज में, पर्यावरण चर को सेट करना और फिर साफ़ करना:

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE

C:\>python -c "assert False"

C:\>SET PYTHONOPTIMIZE=

C:\>python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

यूनिक्स में समान ( संबंधित कार्यक्षमता के लिए सेट और अनसेट का उपयोग करके )

कोड में एकल बिंदु

आप अपना प्रश्न जारी रखें:

यदि एक जोरदार विफल रहता है, मैं नहीं चाहता कि यह एक जोर फेंकना है, लेकिन जा रहा रखने के लिए।

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

if False:
    assert False, "we know this fails, but we don't get here"

या आप दावे को पकड़ सकते हैं:

try:
    assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
    print(repr(e))

जो प्रिंट करता है:

AssertionError('this code runs, fails, and the exception is caught')

और तुम उस बिंदु से चलते रहोगे जिसे तुमने संभाला है AssertionError

संदर्भ

से प्रलेखन :assert

इस तरह एक जोरदार बयान:

assert expression #, optional_message

के बराबर है

if __debug__:
    if not expression: raise AssertionError #(optional_message)

तथा,

अंतर्निहित वैरिएबल __debug__है Trueसामान्य परिस्थितियों में, Falseजब अनुकूलन अनुरोध किया जाता है (आदेश पंक्ति विकल्प -O)।

और आगे

असाइनमेंट __debug__अवैध हैं। इंटरप्रेटर शुरू होने पर अंतर्निहित चर के लिए मूल्य निर्धारित किया जाता है।

उपयोग डॉक्स से:

-O

बुनियादी अनुकूलन चालू करें। यह .pyc से .pyo तक संकलित (बाइटकोड) फ़ाइलों के लिए फ़ाइल नाम एक्सटेंशन को बदलता है। PYTHONOPTIMIZE भी देखें।

तथा

PYTHONOPTIMIZE

यदि यह एक गैर-खाली स्ट्रिंग पर सेट है, तो यह -Oविकल्प को निर्दिष्ट करने के बराबर है । यदि पूर्णांक पर सेट किया जाता है, तो यह -Oकई बार निर्दिष्ट करने के बराबर है ।


क्या in सिंगल पॉइंट इन कोड ’के मामले में विफल रहने वाले कोड को छोड़ना संभव होगा? मैंने __debug__झूठा करने की कोशिश की, लेकिन इसकी अनुमति नहीं है।
Matthijs

1
@Matthijs आप या तो यह सुनिश्चित कर सकते हैं कि नियंत्रण प्रवाह उस तक नहीं पहुंचे (उदाहरण के लिए if False: assert False) या आप जोर त्रुटि को पकड़ सकते हैं। वो आपकी पसंद हैं। अपने प्रश्न का उत्तर देने के लिए अद्यतन करें।
हारून हॉल

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

2
आप फ़ंक्शन के बाइटकोड को फिर से लिख सकते हैं, एएसटी को फिर से लिख सकते हैं, या फ़ंक्शन को फिर से लिख सकते हैं। (मैन्युअल या प्रोग्रामिक रूप से, दोनों के लिए)। एएसटी को फिर से शुरू करना संभवतः सबसे विश्वसनीय दृष्टिकोण होगा ("बस" Assertवस्तुओं के साथ Passवस्तुओं को बदलें )। एक संदर्भ प्रबंधक इसके लिए सीधे काम नहीं करेगा, लेकिन आपके पास किसी तरह का तंत्र हो सकता है जो उस तरह से सजाए गए कार्यों का उपयोग करता है। बावजूद, मैं इसकी सिफारिश नहीं करता। मुझे आपके ऐसा करने की इच्छा के कारण पर संदेह है कि क्या आप ऐसे कोड को कॉल कर रहे हैं जिन्हें आप नियंत्रित नहीं करते हैं और AsorionErrors प्राप्त कर रहे हैं। यदि हां, तो आपको एक अलग फिक्स खोजने की आवश्यकता है।
हारून हॉल

60

-O ध्वज के साथ अजगर को बुलाओ:

test.py:

assert(False)
print 'Done'

आउटपुट:

C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    assert(False)
AssertionError

C:\temp\py>C:\Python26\python.exe -O test.py
Done

9
मुखर एक फ़ंक्शन नहीं है, इसलिए Parens अतिसुंदर हैं।
हारून हॉल

15

पहले से दिए गए दो उत्तर दोनों मान्य हैं (पायथन को या तो -Oया -OOकमांड लाइन पर कॉल करें )।

यहाँ उनके बीच अंतर है:

  • -Oबुनियादी अनुकूलन चालू करें। यह .pyc से .pyo तक संकलित (बाइटकोड) फ़ाइलों के लिए फ़ाइल नाम एक्सटेंशन को बदलता है।

  • -OOत्यागें docstrings अलावा करने के लिए -Oअनुकूलन।

( पायथन प्रलेखन से )



3

आपको (अधिकांश) दावे को अक्षम नहीं करना चाहिए । जब ध्यान कहीं और होता है तो वे अप्रत्याशित त्रुटियों को पकड़ लेते हैं। नियम 5 को "दस की शक्ति" में देखें ।

इसके बजाय, कुछ महंगी जाँचों को सुरक्षित रखें:

import logging
logger = logging.getLogger(__name__)

if logger.getEffectiveLevel() < logging.DEBUG:
    ok = check_expensive_property()
    assert ok, 'Run !'

महत्वपूर्ण assertविवरण रखने का एक तरीका, और बयानों को अनुकूलित करने की अनुमति देना उन्हें चयन विवरण के भीतर उठाकर है:

if foo_is_broken():
    raise AssertionError('Foo is broken!')

1
//, समस्या यह है कि, हालांकि, बयान अभी भी चक्रवाती जटिलता में जोड़ता है, और त्रुटि से निपटने को बाकी को संभालना चाहिए?
नाथन बासानी

1
ऊपर बताए अनुसार लगाए जाने वाले दावे महंगी कॉल हैं जो निष्पादन को काफी धीमा करते हैं। कुछ एल्गोरिदम के लिए, इस तरह के चेक पूरे कार्यक्रम की तुलना में अधिक समय के लिए आदेश ले सकते हैं। शुद्धता की जाँच करने के लिए एक ही एल्गोरिथ्म के एक भोले लेकिन सरल कार्यान्वयन (त्रुटियों की संभावना कम होने की संभावना) को चलाने के बारे में सोचें। या सामान्य ऑपरेशन के लिए प्रश्न से बाहर निकलने वाली किसी चीज की संपूर्ण जांच द्वारा जांच।
Ioannis Filippidis

मुझे पठनीयता में कोई समस्या नहीं दिख रही है, क्योंकि इस तरह के बयान से कोड में नेस्टिंग नहीं जुड़ती है। इसे फंक्शन कॉल के रूप में एक्सट्रैक्ट करते हुए, अगर यह एक मुद्दा है, तो इसे रास्ते से बाहर कर सकते हैं (और मुझे उम्मीद है कि इस तरह के रिफैक्टिंग को साइक्लोमैटिक जटिलता को कम करना चाहिए)। किसी भी घटना में, चक्रवाती जटिलता को सुरक्षा जांच को नियंत्रित नहीं करना चाहिए।
Ioannis Filippidis

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