自定义python装饰器检查函数



下面是一个函数示例:

def test_function(test_df):
test_df = do_something1(test_df)
test_df = do_something2(test_df)
test_df = do_something3(test_df)
return test_df

输入一个pandas数据框,在输入的数据框上调用一些其他函数,并在最后输出。

我的问题是,是否有一种方法来定义一个python包装器(或任何其他方法),检查每一行后,如果你输入的数据框(test_df)是空的,如果是这样,返回一个空的数据框?我这样做的目的是,如果这些函数中的任何一个过滤数据,使test_df为空,则代码将在任何后续函数调用中中断。与我正在寻找的包装器等效的函数是:

def test_function(test_df):
test_df = do_something1(test_df)
if test_df.empty:
return pd.DataFrame()
test_df = do_something2(test_df)
if test_df.empty:
return pd.DataFrame()
test_df = do_something3(test_df)
return test_df

我认为对于一些函数调用,空检查是好的,但我认为这会降低可读性,并且随着函数调用的数量增加,它会变得越来越混乱。

我考虑过定义自定义包装器,但它们似乎是将功能作为一个整体,而不是逐行。还研究了上下文管理器,但它似乎不太适合我的目的。并不是真的想要改变代码太多,因此一个好的包装器是理想的。任何其他具有相同输出的干净解决方案都会很好。

我只会使用循环。

def test_function(test_df):
for f in [do_something1, do_something2, do_something3]:
test_df = f(test_df)
if test_df.empty:
return pd.DataFrame()
return test_df

装饰符不是用来修改被装饰函数的内容的。因此,根据您的问题的精神,您不能(或至少不应该)为test_function创建装饰器。当你想在函数调用之前和/或之后添加一些行为时,它们工作得最好。

如果你想要一个装饰符,你可以在调用的函数中使用它,它看起来像这样:

# the decorator is handed the function being decorated
def decorator(func):
# define a function that will be called instead
# of the decorated function
def wrapper(df):
# call the function being decorated
result = func(df)
if result.empty:
return pd.DataFrame()
return result
# return the function that will replace
# the function being decorated
return wrapper
@decorator
def do_something1(df):
# some code
return df
@decorator
def do_something2(df):
# some code
return df
@decorator
def do_something3(df):
# some code
return df
def test_function(test_df):
test_df = do_something1(test_df)
test_df = do_something2(test_df)
test_df = do_something3(test_df)
return test_df

修饰函数相当于:

def decorator(func):
def wrapper(df):
result = func(df)
if result.empty:
return pd.DataFrame()
return result
return wrapper
# The function to decorate
def do_something2(df):
return df
do_something2 = decorator(do_something2)

你有效地用函数的包装版本替换该函数。

或者,您可以为结果创建一个包装器,这意味着不需要在定义中添加额外的代码。

def workable_result(df):
if df.empty:
return pd.DataFrame()
return df
def test_function(test_df):
test_df = workable_result(do_something1(test_df))
test_df = workable_result(do_something2(test_df))
test_df = do_something3(test_df)
return test_df

相关内容

  • 没有找到相关文章

最新更新