python - 如何在 Python 的方法装饰器中使用类属性?
问题描述
我有一个负责记录的装饰器。例如这样的:
import logging
import functools
from typing import Callable
def log_container(func: Callable, logger=None):
if logger is None:
logger = logging.getLogger("default")
@functools.wraps(func)
def wrapper(*args, **kwargs):
logger.info(f"{func.__qualname__} started.")
result = func(*args, **kwargs)
logger.info(f"{func.__qualname__} ended.")
return result
return wrapper
我有一个具有不同记录器作为属性的类,我想将该记录器作为装饰器参数。这可能吗?如果是这样,如何?
class Dummy:
logger = logging.getLogger("Dummy")
@log_container(logger=Dummy.logger)
def do_something(self):
pass
解决方案
你的装饰器,正如它目前定义的那样,不起作用。您不能将装饰函数与参数一起传递,因为装饰器本身只接受一个参数:它func
本身。如果你想让你的装饰器接受一个参数,你需要将装饰器嵌套更深一层。现在变成一个返回装饰器的函数:
def log_container(logger=None):
if logger is None:
logger = logging.getLogger("default")
def inner(func: Callable):
@functools.wraps(func)
def wrapper(*args, **kwargs):
logger.info(f"{func.__qualname__} started.")
result = func(*args, **kwargs)
logger.info(f"{func.__qualname__} ended.")
return result
return wrapper
return inner
然后在为类装饰方法时Dummy
,不要使用Dummy.logger
因为Dummy
直到类定义结束才定义,而是可以logger
直接访问类属性。
class Dummy:
logger = logging.getLogger("Dummy")
@log_container(logger=logger)
def do_something(self):
pass
# Use default logger
@log_container()
def do_something_else(self):
pass
推荐阅读
- c# - 从 C# 运行 PowerShell 脚本
- javascript - 遵循中继分步指南时出现 AST 节点错误
- xcode - 如何从 CLI 构建 DocC 文档
- r - ggplot:有没有更简洁的方式使用主题背景?
- elasticsearch - elasticsearch节点不活跃
- google-sheets - 从工作表 1 中的单元格中调用工作表名称以从具有自定义名称的工作表中调用数据
- nginx - 不要写端口并添加应用程序名称以进行远程访问
- javascript - JSON API 返回未定义
- c# - 创建插入操作,但是在从 Model StudentView -> Student 转换并传递到 InsertStudentAsync 之后,函数返回 null
- python - 在这门课上我可以做得更好吗?Python 类重构