Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多行上执行相同的更改(尝试除外)-python_Python_Exception_Exception Handling_Refactoring_Decorator - Fatal编程技术网

在多行上执行相同的更改(尝试除外)-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) ... 所以我编写了这段代码,一切正常,但突然我发现我需要制作一个日志文件,所以我必须

程序员可以通过多种方式使编程和重构变得更容易、更简单,python在这方面做得非常好

我很好奇,是否有一种更优雅的方法来解决我的问题,而不是用暴力一次又一次地编写相同的代码

情况:

我在写代码。有许多相等的方法使用不同的参数顺序调用

例如,我有以下代码:

...
...
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听起来不错,但您能给我一个提示吗?除了代码中的任何地方,我不必尝试,我只需将异常设置为打印到日志?