[英]Python: decorator/wrapper for try/except statement
I have some blocks of code which need to be wrapped by function. 我有一些代码块需要按功能包装。
try:
if config.DEVELOPMENT == True:
# do_some_stuff
except:
logger.info("Config is not set for development")
Then I'll do again: 然后我再做一次:
try:
if config.DEVELOPMENT == True:
# do_some_another_stuff
except:
logger.info("Config is not set for development")
So, how can I wrap this "do_some_stuff" and "do_some_another_stuff"? 那么,如何包装这个“ do_some_stuff”和“ do_some_another_stuff”呢?
I'm trying to write function with contextmanager: 我正在尝试使用contextmanager编写函数:
@contextmanager
def try_dev_config(name):
try:
if name is not None:
yield
except Exception as e:
print "not dev config"
with try_dev_config("config.DEVELOPMENT"):
# do_some_stuff
And I got an error: 我得到一个错误:
RuntimeError: generator didn't yield RuntimeError:生成器未产生
You could pass in a function. 您可以传入一个函数。
boolean = True
def pass_this_in():
print("I just did some stuff")
def the_try_except_bit(function):
try:
if boolean:
function()
except:
print("Excepted")
# Calling the above code
the_try_except_bit(pass_this_in)
If you want to reduce the "pass_this_in" definition bit, then you can use lambda function definitions : 如果要减少“ pass_this_in”定义位,则可以使用lambda函数定义 :
pass_this_in = lambda : print("I just did some stuff")
I am not sure that a context manager is the good method to achieve what you want. 我不确定上下文管理器是否是实现所需目标的好方法。 The context manager goal is to provide a mecanism to open/instantiate a resource, give access to it (or not) and close/clean it automatically when you no more need it. 上下文管理器的目标是提供一种机制来打开/实例化资源,提供对资源的访问权限(或不授予访问权限)以及在不再需要它时自动关闭/清理资源。
IMHO, what you need is a decorator . 恕我直言,您需要的是一个装饰器 。 A decorator aims at executing code around a function call. 装饰器旨在围绕函数调用执行代码。 It would force you to put each block of code in a function but I don't think it is so difficult. 这将迫使您将每个代码块放入一个函数中,但我认为这并不那么困难。 You can implement it like this: 您可以这样实现:
class Config(object):
"""for demonstration purpose only: used to have a config.DEVELOPMENT value"""
DEVELOPMENT = True
class Logger(object):
"""for demonstration purpose only: used to have a logger.info method"""
@staticmethod
def info(msg):
print("Logged: {}".format(msg))
def check_dev_config(config, logger):
def dev_config_checker(func):
def wrapper(*args, **kwargs):
try:
if config.DEVELOPMENT:
func(*args, **kwargs)
except Exception as err:
logger.info(
"Config is not set for developpement: {}".format(err))
return wrapper
return dev_config_checker
@check_dev_config(Config, Logger)
def do_stuff_1():
print("stuff 1 done")
@check_dev_config(Config, Logger)
def do_stuff_2():
raise Exception("stuff 2 failed")
do_stuff_1()
do_stuff_2()
This code prints 此代码打印
stuff 1 done
Logged: Config is not set for developpement: stuff 2 failed
Explanations: 说明:
check_dev_config
function is actually a decorator generator which accepts the config
and the logger
as arguments. check_dev_config
函数实际上是一个装饰生成器,它接受config
和logger
作为参数。 dev_config_checker
function which is an actual (and parameterised) decorator, and which accepts a function to decorate as argument. 它返回dev_config_checker
函数,该函数是实际的(且已参数化的)修饰器,并且接受将其修饰为参数的函数。 wrapper
function which will actually run code around the decorated function call. 该装饰器返回一个wrapper
函数,该wrapper
函数实际上将在装饰后的函数调用周围运行代码。 In this function, the decorated function is called inside a try/except
structure and only if the config.DEVELOPMENT
is evaluated to True. 在此函数中,仅在config.DEVELOPMENT
评估为True的情况下,在try/except
结构内部调用修饰函数。 In case of exception, the logger
is used to log an information. 在例外情况下, logger
用于记录信息。 do_stuff_1
, do_stuff_2
and decorated with the check_dev_config
decorator generator, giving it the config
and the logger
. 每个要装饰的代码块都放入一个函数( do_stuff_1
, do_stuff_2
并用check_dev_config
装饰器生成器装饰,为其提供config
和logger
。 do_stuff_2
exception has been catched and the a message has been logged. 如您所见,已捕获到do_stuff_2
异常,并且已记录一条消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.