在多行上执行相同的更改(尝试除外)-python
程序员可以通过多种方式使编程和重构变得更容易、更简单,python在这方面做得非常好 我很好奇,是否有一种更优雅的方法来解决我的问题,而不是用暴力一次又一次地编写相同的代码 情况: 我在写代码。有许多相等的方法使用不同的参数顺序调用 例如,我有以下代码:在多行上执行相同的更改(尝试除外)-python,python,exception,exception-handling,refactoring,decorator,Python,Exception,Exception Handling,Refactoring,Decorator,程序员可以通过多种方式使编程和重构变得更容易、更简单,python在这方面做得非常好 我很好奇,是否有一种更优雅的方法来解决我的问题,而不是用暴力一次又一次地编写相同的代码 情况: 我在写代码。有许多相等的方法使用不同的参数顺序调用 例如,我有以下代码: ... ... my_method(1) my_method(2) my_method(3) my_method(4) ... my_method(10) ... 所以我编写了这段代码,一切正常,但突然我发现我需要制作一个日志文件,所以我必须
...
...
my_method(1)
my_method(2)
my_method(3)
my_method(4)
...
my_method(10)
...
所以我编写了这段代码,一切正常,但突然我发现我需要制作一个日志
文件,所以我必须对所有这些方法进行尝试,因此代码如下所示:
...
...
try:
my_method(3)
except Exception as e:
print_to_file(log.txt,str(e))
...
...
try:
my_method(8)
except Exception as e:
print_to_file(log.txt,str(e))
...
...
我有比更改每个my_方法(x)调用并将其放入try except
子句更好的选择吗?我知道这是一个错误的程序员谁不得不考虑它在一开始,但这些情况发生了
编辑:根据答案-上面的代码是一个简单的例子。在实际代码中,没有给出int参数,但没有给出逻辑的日期,因此我无法将其放入循环中。假设无法生成参数 如果您使用的是python提供的
记录器
,则可以将异常输出重定向到日志,而无需到处放置大量try
块:
import os, sys
import logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)
def handle_exception(exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = handle_exception
if __name__ == "__main__":
raise RuntimeError("Test unhandled")
如果抛出异常,则不需要try
块,它将被写入日志
您可以利用python中的函数完全是一个对象这一事实,编写一个函数,该函数接受另一个函数,运行它,并记录任何异常
def sloppyRun(func, *args, **kwargs):
"""Runs a function, catching all exceptions
and writing them to a log file."""
try:
return func(*args, **kwargs) #running function here
except:
logging.exception(func.__name__ + str(args) + str(kwargs))
#incidentally, the logging module is wonderful. I'd recommend using it.
#It'll even write the traceback to a file.
然后你可以写一些像
sloppyRun(my_method, 8) #note the lack of parens for my_method
您可以像一个上下文管理器或装饰器一样在需要时记录所需内容。如果您打算在使用该函数时始终记录异常,我建议您使用简单的decorator规则,甚至在该函数中尝试使用try-and-except。如果函数不在代码中,或者您不希望它们总是记录,那么我会使用上下文管理器(称为
with.:
)
一个上下文管理器示例代码
import functools
class LoggerContext():
def __enter__(self):
# function that is called on enter of the with context
# we dont need this
pass
def __exit__(self, type, value, traceback):
# If there was an exception, it will be passed to the
# exit function.
# type = type of exception
# value = the string arg of the exception
# traceback object for you to extract the traceback if you need to
if traceback:
# do something with exception like log it etc
print(type, value, traceback)
# If the return value of the exit function is not True, python
# interpreter re-raises the exception. We dont want to re-raise
# the exception
return True
def __call__(self, f):
# this is just to make a context manager a decorator
# so that you could use the @context on a function
@functools.wraps(f)
def decorated(*args, **kwds):
with self:
return f(*args, **kwds)
return decorated
@LoggerContext()
def myMethod(test):
raise FileNotFoundError(test)
def myMethod2(test):
raise TypeError(test)
myMethod('asdf')
with LoggerContext():
myMethod2('asdf')
一个简单的装饰器示例:
import functools
def LoggerDecorator(f):
@functools.wraps(f)
def decorated(*args, **kwds):
try:
return f(*args, **kwds)
except Exception as e:
# do something with exception
print('Exception:', e)
return decorated
@LoggerDecorator
def myMethod3(test):
raise IOError(test)
myMethod3('asdf')
将参数放入一个列表中使用单个try/except对列表中的每个参数调用函数进行迭代您是否尝试过将
try/except
语句放入for
循环中?@millan,您怎么说不能使用循环,args来自何处?为什么不将异常输出重定向到日志,这样您就不需要try块了?@SyntacticFructose听起来不错,但您能给我一个提示吗?除了代码中的任何地方,我不必尝试,我只需将异常设置为打印到日志?