Python警告出现在试图警告用户

2024-09-30 06:28:29 发布

您现在位置:Python中文网/ 问答频道 /正文

但我并没有在代码中使用警告来警告用户。下面是一个基于我在实际代码中遇到的更复杂场景的简单模型:

from warnings import warn
class myClass(object):        
    def __init__(self, numberArg):

        if numberArg > 1000:
            self._tmpTxt = "That's a really big number for this code." + \
                           "Code may take a while to run..."
            warn("\n%s %s" %(numberArg, self._tmpTxt))
            print("If this were real code:")
            print("Actions code takes because this is a big number would happen here.")

        print("If this were real code, it would be doing more stuff here ...")

mc1 = myClass(1001)

在我的实际代码中,当我实例化执行__init__(self, numberArg)的类时,在完成警告之后的所有处理之后,将在最后输出警告。为什么会这样?在

更重要的是,有没有一种方法可以确保先输出警告,然后运行其余代码并交付其输出?在

与这里提供的示例一样,所需的效果是在事件发生之前(而不是之后)警告用户将要发生的事情,并像使用警告格式的警告一样提供输出。在

注意:这个问题是在Windows7环境下的iPython/Jupyter上使用python2.7时遇到的


Tags: 代码用户self警告numberifinitmyclass
1条回答
网友
1楼 · 发布于 2024-09-30 06:28:29

@direprobs在评论中给出了这个问题最简单的答案。在调用warn()之后添加这行代码。在

sys.stderr.flush()

注意:尽管它来自sys库,但您不需要import语句,因为warnings写入stderr并已导入该库。在

可以将此代码复制并粘贴到Python2.7(Jupyter笔记本)中,以快速运行它并查看效果:

实验一(与后面的代码进行比较):

# Note how warnings in this sample are held until after code is run and then output at the end ...

from warnings import warn
from warnings import resetwarnings

class myClass(object):        
    def __init__(self, numberArg):

        if numberArg > 1000:
            self._tmpTxt = "That's a really big number for this code." + \
                           "Code may take a while to run..."
            warn("\n%s %s" %(numberArg, self._tmpTxt), stacklevel=1, category=RuntimeWarning)
                                                       # possible categories (some of them):
                                                       # UserWarning, Warning, RunTimeWarning, ResourceWarning
                                                       # stacklevel was a experiment w/ no visible effect
                                                       # in this instance

            resetwarnings()                            # tried putting this before and after the warn()
            print("If this were real code:")
            print("Actions code takes because this is a big number would happen here.")

        print("If this were real code, it would be doing more stuff here ...")

mc1 = myClass(1001)

实验二:

^{pr2}$

实验三:

# code provided as an experiment ... may be updated later with a more useful example ...
# in theory, filterwarnings should help shake out repeat warnings if used with right arguments
#   * note how our loop causes the content to print twice, and in theory, the 3 instances of warnings
#   * occur twice each for 6 possible output warnings
#   * each new occurance (3 of them) still outputs, but when the same ones come up again, they don't
#   * we get 3 instead of 6 warnings ... this should be the effect of filterwarning("once")
#     in this instance

# help on this: https://docs.python.org/3/library/warnings.html#warning-filter
#               in this example:
#                  "once" arg = print only the first occurrence of matching warnings, regardless of location

from warnings import warn
from warnings import resetwarnings
from warnings import filterwarnings

class myClass(object):        
    def __init__(self, numberArg):

        for i in [1,2]:

            if numberArg > 1000:
                print("loop count %d:" %(i))
                self._tmpTxt = "That's a really big number for this code." + \
                               "Code may take a while to run..."
                filterwarnings("once")
                warn("\n%s %s" %(numberArg, self._tmpTxt), stacklevel=1, category=RuntimeWarning)
                sys.stderr.flush() # this provides warning ahead of the output instead of after it
                # resetwarnings()  # no noticeable effect on the code
                print("If this were real code:")
                print("Actions code takes because this is a big number would happen here.")

            if numberArg > 20000:
                self._tmpTxt = "That's a really really really big number for this code." + \
                               "Code may take a while to run..."                
                filterwarnings("once", "\nFW: %s %s" %(numberArg, self._tmpTxt))
                warn("\n%s %s" %(numberArg, self._tmpTxt), stacklevel=0)
                # resetwarnings()  # no noticeable effect on the code
                sys.stderr.flush() # this provides warning ahead of the output instead of after it

            print("loop count %d:" %(i))    
            print("If this were real code, it would be doing more stuff here ...")

mc1 = myClass(1001)
print("====================")
mc2 = myClass(20001)

稍后在github上查找此代码。发布在这里是为了帮助其他人研究如何使用warnings。在

相关问题 更多 >

    热门问题