@direprobs fourni la réponse la plus simple à cette question dans les commentaires. Ajoutez cette ligne de code après l'appel à warn()
.
sys.stderr.flush()
Note: Bien qu'il provient de la bibliothèque sys
, vous n'avez pas besoin d'une déclaration import
parce warnings
écrit à stderr
et les importations déjà la bibliothèque.
Ce code peut être copié et-collé dans Python 2.7 (Jupyter Notebooks) pour exécuter rapidement et voir les effets:
Expérience Un (par rapport au code qui suit):
# 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)
Expérience Deux:
# 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)
Expérience trois:
# 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)
Recherchez ce code sur GitHub plus tard. Posté ici pour aider les autres enquêtant sur la façon d'utiliser warnings
.
'warn' n'a pas été retardé depuis la ligne de commande. Le message va à stderr, peut-être que votre environnement tarde à le voir. – tdelaney
J'aime la façon dont warn() se comporte. Il affiche le nom du module incriminé, le numéro de la ligne de code, puis le formatage du message d'avertissement proposé en rose pour signaler à l'utilisateur que quelque chose ne va pas. Y a-t-il un moyen de contourner le problème? Idées bienvenues. (Juste essayer de rendre mon code meilleur). Note: en ce qui concerne la théorie du retard, alors que le code dans cet exemple est instable, dans mon code réel, un calcul a pris 3+ minutes à compléter, et l'avertissement est toujours apparu à la fin. S'il s'agit d'un retard, il semble que ce soit «retarder jusqu'à ce que tout le code soit terminé» plutôt que «basé sur le temps». – TMWP
Qu'en est-il de flushing stderr? Cela aiderait-il de toute façon? – direprobs