在尝试警告用户关于

时间:2017-04-19 20:37:47

标签: python class oop ipython warnings

我在目标代码中使用警告来提醒用户发生了某些事情但没有停止代码。下面是一个基于我在实际代码中遇到的更复杂场景的简单模型:

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)的类时,警告在完成警告之后的所有处理之后输出。为什么会这样?

更重要的是,有没有办法确保首先输出警告然后我的其余代码运行并提供其输出?

与此处提供的示例一样,期望的效果是提醒用户在事件发生之前会发生什么,而不是事后发生,并像警告格式的警告一样传递输出。

注意:在Windows 7环境中使用iPython / Jupyter上的Python 2.7遇到此问题

1 个答案:

答案 0 :(得分:3)

@direprobs在评论中提供了这个问题的最简单答案。在调用public Gmail_Login (WebDriver d) { super(d); this.driver = d; } 后添加此行代码。

warn()

注意:虽然它来自sys.stderr.flush()库,但您不需要sys语句,因为import写入warnings并已导入库。

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

第一项实验(与其后的代码进行比较):

stderr

实验二:

# 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)

实验三:

# In this case, we want the warning to come before code execution.  This is easily fixed as shown below.
# note: removed some extraneous useless stuff, the line to look for is sys.stderr.flush()

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), category=Warning)            
            sys.stderr.flush()                         # put this after each warn() to make it output more immediately
            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)  

稍后在github上查找此代码。将其发布在此处以帮助其他人调查如何使用# 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)