Python Decorator进行1个位置论点,但修改Pytest后给出了5个

发布于 2025-01-27 10:05:51 字数 3174 浏览 2 评论 0原文

我会感谢以下代码的一些帮助,因为我对Python仍然相对较新,尽管有无数日子试图弄清楚我出错的地方,但我似乎无法发现自己​​犯的错误。

我已经从媒体上的文章中调整了以下代码,以创建伐木装饰器,然后增强其尝试,并从日志中“编辑pandas df and Dictionary”。使用功能引起了我的Pytest和Pytest固定装置的问题。堆栈溢出的帖子建议放下功能上的功能,以支持装饰器。

def log_decorator(_func=None):
    def log_decorator_info(func):
        def log_decorator_wrapper(*args, **kwargs):
        
            _logger = Logger()
            logger_obj = _logger.get_logger()

            args_passed_in_function = args_excl_df_dict(*args)
            kwargs_passed_in_function = kwargs_excl_df_dict(**kwargs)
           formatted_arguments = join_args_kwargs(args_passed_in_function,kwargs_passed_in_function)
        
            py_file_caller = getframeinfo(stack()[1][0])
            extra_args = { 'func_name_override': func.__name__,'file_name_override': os.path.basename(py_file_caller.filename) }

            """ Before to the function execution, log function details."""
            logger_obj.info(f"Begin function - Arguments: {formatted_arguments}", extra=extra_args)
        
            try:
                """ log return value from the function """
            
                args_returned_from_function = args_excl_df_dict(func(*args))
                kwargs_returned_from_function = []
                formatted_arguments = join_args_kwargs(args_returned_from_function,kwargs_returned_from_function)
            
                logger_obj.info(f"End function - Returned: {formatted_arguments}", extra=extra_args)
       
            except:
                """log exception if occurs in function"""
                error_raised = str(sys.exc_info()[1])
            
                logger_obj.error(f"Exception: {str(sys.exc_info()[1])}",extra=extra_args)
            
                msg_to_send = f"{func.__name__} {error_raised}"
               send_alert(APP_NAME,msg_to_send,'error')
            
               raise
            return func(*args, **kwargs)
        return decorator.decorator(log_decorator_wrapper, func)
    if _func is None:
        return log_decorator_info
    else:
        return log_decorator_info(_func)

改编上述代码后,我无法弄清楚是什么导致以下错误

args_returned_from_function = args_excl_df_dict(func(*args)) TypeError:test_me()进行4个位置参数,但给出了5个

功能是日志装饰器所依赖的其他功能

def args_excl_df_dict(*args):
    args_list = []
    for a in args:
        if isinstance(a,(pd.DataFrame,dict)):
            a = 'redacted from log'
            args_list.append(repr(a))
        else: 
            args_list.append(repr(a))
    return args_list

def kwargs_excl_df_dict(**kwargs):
    kwargs_list = []
    for k, v in kwargs.items():
        if isinstance(v,(dict,pd.DataFrame)):
            v = 'redacted from log'
            kwargs_list.append(f"{k}={v!r}")
        else:
            kwargs_list.append(f"{k}={v!r}")
    return kwargs_list

def join_args_kwargs(args,kwargs):

    formatted_arguments = ", ".join(args + kwargs)
    return str(formatted_arguments)

是调用装饰器的代码

@log_decorator.log_decorator()
def test_me(a, b, c, d):
    return a, b

test_me(string, number, dictionary, pandas_df)

I'd appreciate some help with the following code, as I'm still relatively new to Python, and despite countless days trying to figure out where i'm going wrong, i cant seem to spot the error i'm making.

I've adapted the following code from an article on medium to create a logging decorator and then enhanced it to try and "redact pandas df and dictionary" from the logs. Using functools caused me a problem with pytest and pytest fixtures. A post on stack overflow suggested dropping functools in favour of decorators.

def log_decorator(_func=None):
    def log_decorator_info(func):
        def log_decorator_wrapper(*args, **kwargs):
        
            _logger = Logger()
            logger_obj = _logger.get_logger()

            args_passed_in_function = args_excl_df_dict(*args)
            kwargs_passed_in_function = kwargs_excl_df_dict(**kwargs)
           formatted_arguments = join_args_kwargs(args_passed_in_function,kwargs_passed_in_function)
        
            py_file_caller = getframeinfo(stack()[1][0])
            extra_args = { 'func_name_override': func.__name__,'file_name_override': os.path.basename(py_file_caller.filename) }

            """ Before to the function execution, log function details."""
            logger_obj.info(f"Begin function - Arguments: {formatted_arguments}", extra=extra_args)
        
            try:
                """ log return value from the function """
            
                args_returned_from_function = args_excl_df_dict(func(*args))
                kwargs_returned_from_function = []
                formatted_arguments = join_args_kwargs(args_returned_from_function,kwargs_returned_from_function)
            
                logger_obj.info(f"End function - Returned: {formatted_arguments}", extra=extra_args)
       
            except:
                """log exception if occurs in function"""
                error_raised = str(sys.exc_info()[1])
            
                logger_obj.error(f"Exception: {str(sys.exc_info()[1])}",extra=extra_args)
            
                msg_to_send = f"{func.__name__} {error_raised}"
               send_alert(APP_NAME,msg_to_send,'error')
            
               raise
            return func(*args, **kwargs)
        return decorator.decorator(log_decorator_wrapper, func)
    if _func is None:
        return log_decorator_info
    else:
        return log_decorator_info(_func)

Having adapted the above code i cant figure out what is causing the following error

args_returned_from_function = args_excl_df_dict(func(*args))
TypeError: test_me() takes 4 positional arguments but 5 were given

Other functions which the log decorator relies on

def args_excl_df_dict(*args):
    args_list = []
    for a in args:
        if isinstance(a,(pd.DataFrame,dict)):
            a = 'redacted from log'
            args_list.append(repr(a))
        else: 
            args_list.append(repr(a))
    return args_list

def kwargs_excl_df_dict(**kwargs):
    kwargs_list = []
    for k, v in kwargs.items():
        if isinstance(v,(dict,pd.DataFrame)):
            v = 'redacted from log'
            kwargs_list.append(f"{k}={v!r}")
        else:
            kwargs_list.append(f"{k}={v!r}")
    return kwargs_list

def join_args_kwargs(args,kwargs):

    formatted_arguments = ", ".join(args + kwargs)
    return str(formatted_arguments)

This is the code calling the decorator

@log_decorator.log_decorator()
def test_me(a, b, c, d):
    return a, b

test_me(string, number, dictionary, pandas_df)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遮云壑 2025-02-03 10:05:51

我认为问题在于,包装器将功能作为该功能的参数包含。

尝试添加此行,看看它是否有助于

args = args[1:]

将log_decorator_wrapper函数伸向顶部。像这样。

def log_decorator(_func=None):
    def log_decorator_info(func):
        def log_decorator_wrapper(*args, **kwargs):

            args = args[1:]   # < -------------------here
            _logger = Logger()
            logger_obj = _logger.get_logger()

            args_passed_in_function = args_excl_df_dict(*args)
            kwargs_passed_in_function = kwargs_excl_df_dict(**kwargs)
           formatted_arguments = join_args_kwargs(args_passed_in_function,kwargs_passed_in_function)
        
            py_file_caller = getframeinfo(stack()[1][0])
            extra_args = { 'func_name_override': func.__name__,'file_name_override': os.path.basename(py_file_caller.filename) }

            """ Before to the function execution, log function details."""
            logger_obj.info(f"Begin function - Arguments: {formatted_arguments}", extra=extra_args)
        
            try:
                """ log return value from the function """
            
                args_returned_from_function = args_excl_df_dict(func(*args))
                kwargs_returned_from_function = []
                formatted_arguments = join_args_kwargs(args_returned_from_function,kwargs_returned_from_function)
            
                logger_obj.info(f"End function - Returned: {formatted_arguments}", extra=extra_args)
       
            except:
                """log exception if occurs in function"""
                error_raised = str(sys.exc_info()[1])
            
                logger_obj.error(f"Exception: {str(sys.exc_info()[1])}",extra=extra_args)
            
                msg_to_send = f"{func.__name__} {error_raised}"
               send_alert(APP_NAME,msg_to_send,'error')
            
               raise
            return func(*args, **kwargs)

        return decorator.decorator(log_decorator_wrapper, func)
    if _func is None:
        return log_decorator_info
    else:
        return log_decorator_info(_func)

I think the problem is that the wrapper is including the function as an argument to the function.

Try adding this line and see if it helps

args = args[1:]

intor your log_decorator_wrapper function towards the top. Like this.

def log_decorator(_func=None):
    def log_decorator_info(func):
        def log_decorator_wrapper(*args, **kwargs):

            args = args[1:]   # < -------------------here
            _logger = Logger()
            logger_obj = _logger.get_logger()

            args_passed_in_function = args_excl_df_dict(*args)
            kwargs_passed_in_function = kwargs_excl_df_dict(**kwargs)
           formatted_arguments = join_args_kwargs(args_passed_in_function,kwargs_passed_in_function)
        
            py_file_caller = getframeinfo(stack()[1][0])
            extra_args = { 'func_name_override': func.__name__,'file_name_override': os.path.basename(py_file_caller.filename) }

            """ Before to the function execution, log function details."""
            logger_obj.info(f"Begin function - Arguments: {formatted_arguments}", extra=extra_args)
        
            try:
                """ log return value from the function """
            
                args_returned_from_function = args_excl_df_dict(func(*args))
                kwargs_returned_from_function = []
                formatted_arguments = join_args_kwargs(args_returned_from_function,kwargs_returned_from_function)
            
                logger_obj.info(f"End function - Returned: {formatted_arguments}", extra=extra_args)
       
            except:
                """log exception if occurs in function"""
                error_raised = str(sys.exc_info()[1])
            
                logger_obj.error(f"Exception: {str(sys.exc_info()[1])}",extra=extra_args)
            
                msg_to_send = f"{func.__name__} {error_raised}"
               send_alert(APP_NAME,msg_to_send,'error')
            
               raise
            return func(*args, **kwargs)

        return decorator.decorator(log_decorator_wrapper, func)
    if _func is None:
        return log_decorator_info
    else:
        return log_decorator_info(_func)
治碍 2025-02-03 10:05:51

如果您的代码与编辑器中的代码相同,则可以查看前三个功能的缩进。然后从那里开始向下移动

If your code is as is in your editor, maybe look at the indentation on the first three functions. Then start from there to move down

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文