पायथन में, कोई भी चेतावनी को कैसे पकड़ता है जैसे कि वे अपवाद थे?


103

एक तृतीय-पक्ष पुस्तकालय (सी में लिखा गया) जो मैं अपने पायथन कोड में उपयोग करता हूं, चेतावनी जारी कर रहा है। मैं try exceptइन चेतावनियों को अच्छी तरह से संभालने के लिए वाक्यविन्यास का उपयोग करने में सक्षम होना चाहता हूं । क्या इसे करने का कोई तरीका है?


2
क्या केवल पाठ संदेश लिखे जाने वाले चेतावनी स्टडर हैं?
फेनिकसो

1
फेंनिको: मुझे यकीन नहीं है, असली चेतावनी की तरह लगता है
बोरिस गोरेलिक

1
आप "वास्तविक चेतावनी" कैसे पहचानते हैं? मैंने सोचा कि सी में आपको संकलन के दौरान वास्तविक चेतावनी मिलती है।
फेनीकोसो

warnings.filterwarningsवास्तव में आप क्या चाहते हैं, मुझे समझ नहीं आ रहा है कि आपका मुद्दा क्या है?
रोश ऑक्सीमोरोन

4
@Fenikso, @ रोश ऑक्सीमोरोन आप सही थे। मेरी गलती। warnings.filterwarnigns('error')नौकरी करता है। मुझे इसका मूल उत्तर नहीं मिला, जिसने इस समाधान का प्रस्ताव दिया था
बोरिस गोरेलिक

जवाबों:


51

अजगर पुस्तिका ( 27.6.4 परीक्षण चेतावनी ) से उद्धृत करने के लिए :

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)

6
यहाँ एक उत्तर है, जो आपको बताता है कि try exceptवाक्य रचना का उपयोग कैसे करें ।
अनपिड्रा

यह नीकस के जवाब पर फायदा है, कि अगर fnxकुछ वापस करता है, तो आप उस परिणाम को रखते हैं (और अभी भी चेतावनी का प्रबंधन कर सकते हैं)।
पिएत्रो बैटिस्टन

यह ओपी के सवाल का जवाब नहीं देता है, जो कि परीक्षण के बारे में नहीं, बल्कि पत्नियों को संभालने के बारे में था। हालांकि, नीचे दिए गए जवाबों से पता चलता है कि चेतावनी को कैसे संभालना है।
Biggsy

बस ध्यान दें कि उपरोक्त फ़ंक्शन काम नहीं करेगा यदि आपका फ़ंक्शन केवल रुक-रुक कर चेतावनी देता है क्योंकि उस स्थिति में जो fxn()चेतावनी नहीं लौटाता है, तो wएक खाली सूची होगी। तो wएक खाली सूची (यानी है []), तो कोड चलाने आपको निम्न त्रुटि दे देंगे: IndexError: list index out of range। यदि आप केवल पकड़ी गई चेतावनी के गुणों को प्रारूपित करना या जांचना चाहते हैं, तो फॉर-लूप का उपयोग करना बेहतर है:for x in w: print(f'{x.category.__name__}: {str(x.message)}')
स्टीवन एम। मोर्टिमर

130

चेतावनियों को संभालने के लिए त्रुटियों के रूप में इसका उपयोग करें:

import warnings
warnings.filterwarnings("error")

इसके बाद आप त्रुटियों के रूप में चेतावनी को पकड़ने में सक्षम होंगे, जैसे यह काम करेगा:

try:
    some_heavy_calculations()
except RuntimeWarning:
    import ipdb; ipdb.set_trace()

PS ने इस उत्तर को जोड़ा क्योंकि टिप्पणियों में सबसे अच्छे उत्तर में गलत वर्तनी है: filterwarnignsइसके बजाय filterwarnings


8
और यदि आप केवल एक स्टैक ट्रेस देखना चाहते हैं, तो पहले दो पंक्तियाँ आपको चाहिए।
z0r

5
यह पूर्ण है। मैं चाहता था कि चेतावनी जारी होते ही मैं अपनी स्क्रिप्ट को क्रियान्वित करना बंद कर दूं, ताकि मैं प्रासंगिक डिबग जानकारी को प्रिंट कर सकूं और समस्या को ठीक कर सकूं।
प्रवीण

1
आपको कम से कम अजगर में filterwarningsपकड़ने के लिए कॉल की आवश्यकता नहीं है Warnings। यह सिर्फ काम करता है।
n

1
स्वीकृत उत्तर ओपी के प्रश्न का उत्तर नहीं देता है। यह उत्तर देता है। यह वह उत्तर है जिसकी मुझे तलाश थी जब मेरी खोज को यह प्रश्न मिला।
Biggsy


15

यहां एक विविधता है जो यह स्पष्ट करती है कि केवल आपके कस्टम चेतावनियों के साथ कैसे काम किया जाए।

import warnings
with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")

    # Call some code that triggers a custom warning.
    functionThatRaisesWarning()

    # ignore any non-custom warnings that may be in the list
    w = filter(lambda i: issubclass(i.category, UserWarning), w)

    if len(w):
        # do something with the first warning
        email_admins(w[0].message)

4

कुछ मामलों में, आपको चेतावनियों को त्रुटियों में बदलने के लिए ctypes का उपयोग करने की आवश्यकता है। उदाहरण के लिए:

str(b'test')  # no error
import warnings
warnings.simplefilter('error', BytesWarning)
str(b'test')  # still no error
import ctypes
ctypes.c_int.in_dll(ctypes.pythonapi, 'Py_BytesWarningFlag').value = 2
str(b'test')  # this raises an error

यह उत्तर रचनात्मक रूप से यह दिखाने के लिए है कि केवल कुछ चेतावनी प्रकारों में त्रुटि कैसे करें। लगभग किसी भी बड़े सॉफ़्टवेयर प्रोजेक्ट के लिए, यदि आप करते हैं तो warnings.simplefilter('error')आपको लॉग में देखी गई चेतावनी के लिए ट्रेसबैक नहीं मिलेगा, बल्कि इसके बजाय पहले से फ़िल्टर किए गए चेतावनियों से ट्रेसबैक प्राप्त करें। का उपयोग करते हुए simplefilterभी अगर आप कुछ CLI मंगलाचरण है आपका जवाब पर पहुंचने के लिए तेज तरीका है।
एलनसे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.