Reputation: 60044
I have a loop which looks like this:
errors += 1
for ...:
...
if ...:
logger.error(...)
errors += 1
continue
...
if ...:
logger.error(...)
errors += 1
continue
...
if ...:
logger.error(...)
errors += 1
continue
...
logger.info("%d errors",errors)
I wonder what the pythonic way to make it more readable is.
I can do
def e (fmt, *args):
logger.error(fmt, *args)
errors += 1
for ...:
...
if ...:
e(...)
continue
...
if ...:
e(...)
continue
...
if ...:
e(...)
continue
...
logger.info("%d errors",errors)
or even
def e (cond, fmt, *args):
if cond:
logger.error(fmt, *args)
errors += 1
return cond
for ...:
...
if e(...):
continue
...
if e(...):
continue
...
if e(...)
continue
...
logger.info("%d errors",errors)
however, it doesn't look like I can do any better (no way to continue
from inside e
).
Right?
(I think I can raise StopIteration
in e
to abort the iteration, but not something like a non-existent ContinueIteration
).
Upvotes: 2
Views: 69
Reputation: 21453
you could create a wrapper for the logger
that record how many times error
is called:
class CountingLogger:
def __init__(self, real_logger, initial_errors=0):
self.logger = real_logger
self.errors = initial_errors
def error(self, *args, **kw):
self.logger.error(*args, **kw)
self.errors += 1
Then you'd use something like e = CountingLogger(logger)
and call e.error()
inside the loop and afterwards you can access e.errors
to see how many times it was called. (naming could be better, error
the method and errors
the property are a bit too close for comfort)
Upvotes: 0
Reputation: 73470
Feels to me like using exception handling is semantically appropriate and similarly concise as a function without the need for any continue
:
for ...:
try:
# ...
if ...:
raise SomeException(...)
# ...
if ...:
raise SomeException(...)
# ...
if ...:
raise SomeException(...)
# ...
except SomeException as e:
logger.error(e.message)
errors += 1
Upvotes: 4