2017-08-08 10 views
5

के लिए मैं अपने लॉग में इस तरह एक चेतावनी दिखाई:स्टैकट्रेस UserWarning

py.warnings.__init__: WARNING .../bs4/__init__.py:219: UserWarning: "foo" 
    looks like a filename, not markup. You should probably open this file 
    and pass the filehandle into Beautiful Soup 

यह संदेश बहुत ज्यादा मदद नहीं करता है।

मैं यह कहां स्टैकट्रैक देखना चाहता हूं।

कृपया इस चेतावनी की सामग्री को न देखें।

import traceback 
logger.warn('Exc at ...\n%s' % ''.join(traceback.format_stack())) 

लेकिन मैं से बचने के लिए करना चाहते हैं: यह सवाल ब्यूटीफुल सूप :-)

एक आसान समाधान तीसरे पक्ष के कोड (bs4/__init__.py लाइन 219 में) को संशोधित करने और कुछ इस तरह जोड़ने के लिए किया जाएगा के बारे में नहीं है इस। कारण:

  • यह उत्पादन प्रणाली से एक चेतावनी है। मैं स्रोत को बदलना नहीं चाहता हूं।
  • अगली बार इस तरह एक चेतावनी होती है, तो मैं स्टैकट्रेस देखना चाहेंगे तुरंत

वहाँ एक ध्वज है या अजगर जो मैं, बदल सकते हैं न केवल एक लाइन को देखने के लिए की स्थापना, लेकिन जब स्टैकट्रेस ? मुझे इसे डीबग करने के लिए ऊपरी फ्रेम की आवश्यकता है।

इस माहौल में पायथन 2.7 का उपयोग किया जाता है।

उत्तर

2

आप निम्न कार्य करने की आवश्यकता होगी:

  1. बनाएं यदि USER_SITE मौजूद नहीं है:

    : मुद्दा python -c "import site; site._script()", USER_SITE चर सामग्री
  2. निम्न कोड के साथ कि निर्देशिका में जहाँ एक फ़ाइल usercustomize.py देखना

    import traceback 
    import warnings 
    
    
    _old_warn = warnings.warn 
    def warn(*args, **kwargs): 
        tb = traceback.extract_stack() 
        _old_warn(*args, **kwargs) 
        print("".join(traceback.format_list(tb)[:-1])) 
    warnings.warn = warn 
    

    this पर क्रेडिट कोड के लिए उत्तर।

सामान्य रूप से कोड चलाएं। मेरे परीक्षण कोड:

import warnings 

def f(): 
    warnings.warn("foz") 

f() 

प्रक्रिया से पहले:

$ python test_warn.py 
test_warn.py:4: UserWarning: foz 
    warnings.warn("foz") 

के बाद:

$ python test_warn.py 
<USER_SITE_REDACTED>/usercustomize.py:6: UserWarning: foz 
    _old_warn(*args, **kwargs) 
    File "test_warn.py", line 6, in <module> 
    f() 
    File "test_warn.py", line 4, in f 
    warnings.warn("foz") 
+0

ठीक है, मैं देखता हूं। AFAIK इसे बंदर पैचिंग कहा जाता है। हां, मुझे लगता है कि usercustomize.py इस तरह बंदर पैचिंग करने के लिए एक अच्छी जगह है। धन्यवाद। – guettli

+1

@guettli, यह बंदरगाह है। यद्यपि यह इसका उपयोग करने के लिए एक वैध मामला हो सकता है, यह देखते हुए कि स्रोत को बदला नहीं जाना है, और घुसपैठ कोई तर्क नहीं बदलती है - बस प्रभावी रूप से अधिक लॉगिंग जोड़ती है। – RebelWithoutAPulse

1

अगर मैं एक चेतावनी की जड़ मैं आम तौर पर सिर्फ Exceptions को Warnings को बढ़ावा देने खोजना चाहते हैं।

अपने मामले में आप बस warnings.simplefilter या warnings.filterwarnings का उपयोग कर सकते हैं।

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

import warnings 

def func(): 
    warnings.warn('abc', UserWarning) 

def func2(): 
    func() 

# Here I promote all UserWarnings to exceptions, but you could also use "warnings.filterwarnings" 
# to only promote warnings from a specified module or matching a specified message. 
# You may need to check which is most useful/appropriate for you. 
warnings.simplefilter("error", UserWarning) # you might need to reset this later :) 
func2() 

जो एक पूर्ण ट्रैस बैक देता है:

:

--------------------------------------------------------------------------- 
UserWarning        Traceback (most recent call last) 
<ipython-input-11-be791e1071e7> in <module>() 
     8 
     9 warnings.simplefilter("error", UserWarning) 
---> 10 func2() 

<ipython-input-11-be791e1071e7> in func2() 
     5 
     6 def func2(): 
----> 7  func() 
     8 
     9 warnings.simplefilter("error", UserWarning) 

<ipython-input-11-be791e1071e7> in func() 
     2 
     3 def func(): 
----> 4  warnings.warn('abc', UserWarning) 
     5 
     6 def func2(): 

UserWarning: abc 

और आप इस डिबग करने के लिए आप आसानी से पिछले सामना करना पड़ा अपवाद पर अजगर हुक सकता pdb रों चाहते हैं

import pdb 

pdb.pm() 

परिणामस्वरूप:

> <ipython-input-11-be791e1071e7>(4)func() 
-> warnings.warn('abc', UserWarning) 
(Pdb) _________________ 

यह अंतिम सामना के अपवाद के पोस्ट-मॉर्टम विश्लेषण शुरू करता है। जो तुम फ्रेम के माध्यम से खुदाई और चर का निरीक्षण, आदि के लिए सक्षम होना चाहिए


तुम भी एक ध्वज के बारे में पूछा, और वास्तव में वहाँ एक ध्वज है कि, "चेतावनी हैंडलिंग" के लिए सक्षम बनाता -W flag है। यह warnings.filterwarnings फ़ंक्शन की तरह बहुत अधिक है। सुविधा के लिए मैंने अभी -W ध्वज के दस्तावेज की प्रतिलिपि बनाई है:

Warning control. Python’s warning machinery by default prints warning messages to sys.stderr. A typical warning message has the following form:

file:line: category: message 

By default, each warning is printed once for each source line where it occurs. This option controls how often warnings are printed.

Multiple -W options may be given; when a warning matches more than one option, the action for the last matching option is performed. Invalid -W options are ignored (though, a warning message is printed about invalid options when the first warning is issued).

Starting from Python 2.7, DeprecationWarning and its descendants are ignored by default. The -Wd option can be used to re-enable them.

Warnings can also be controlled from within a Python program using the warnings module.

The simplest form of argument is one of the following action strings (or a unique abbreviation) by themselves:

  • ignore

    Ignore all warnings.

  • default

    Explicitly request the default behavior (printing each warning once per source line).

  • all

    Print a warning each time it occurs (this may generate many messages if a warning is triggered repeatedly for the same source line, such as inside a loop).

  • module

    Print each warning only the first time it occurs in each module.

  • once

    Print each warning only the first time it occurs in the program.

  • error:

    Raise an exception instead of printing a warning message.

The full form of argument is:

action:message:category:module:line 

Here, action is as explained above but only applies to messages that match the remaining fields. Empty fields match all values; trailing empty fields may be omitted. The message field matches the start of the warning message printed; this match is case-insensitive. The category field matches the warning category. This must be a class name; the match tests whether the actual warning category of the message is a subclass of the specified warning category. The full class name must be given. The module field matches the (fully-qualified) module name; this match is case-sensitive. The line field matches the line number, where zero matches all line numbers and is thus equivalent to an omitted line number.

+0

मुझे लगता है कि यह आपके एवर में संबोधित नहीं है: अगली बार इस तरह की चेतावनी होती है, मैं तुरंत स्टैकट्रैक देखना चाहूंगा – guettli

+0

यदि आप उन्हें अपवादों के लिए प्रचार करते हैं तो आप तत्काल ट्रेसबैक देखेंगे। या मैंने आपके प्रश्न को गलत समझा? – MSeifert

+0

मैंने कल आपको समाधान समझाया। मुझे लगता है कि अब मैं इसे समझ गया। आप "एक चेतावनी संदेश मुद्रित करने के बजाय अपवाद उठाएं।" मैं इससे बचना चाहूंगा, क्योंकि उत्पादन वातावरण पर चेतावनी होती है, और अब तक यह विकास वातावरण में दोहराने योग्य नहीं है। मैं इस मामले में अपवाद से अपवाद से स्विचिंग से बचना चाहता हूं। – guettli

संबंधित मुद्दे