Python类内装饰器遇两类报错,求助解决方案及私有属性访问问题
问题分析与解决
错误原因及修复方案
错误2:function '__s_operation' lacks a positional argument
你把__s_operation定义成了类的普通实例方法,但在类定义阶段装饰其他方法时,Python会尝试将类作为self参数传入装饰器,而装饰器只接收func一个参数,因此触发参数缺失错误。
修复:将__s_operation标记为静态方法,避免自动传入self参数:
import functools import logging logger = logging.getLogger(__name__) class ClientHandler: def __init__(self, c_ident): self.__is_dead = False self.c_ident = c_ident # 修正初始化参数,原代码未传入c_ident @staticmethod # 添加静态方法装饰器,避免自动传入self def __s_operation(func): @functools.wraps(func) def check(*args, **kwargs): # 兼容关键字参数 self = args[0] if not self.__is_dead: return func(*args, **kwargs) # 返回被装饰方法的返回值 else: logger.error( "couldn't proceed - client {} is dead!".format( self.c_ident ) ) return check @__s_operation def __receive_m(self, size) -> bytes: # 示例实现 return b"received data" @__s_operation def close_c(self, message: str) -> None: # 示例实现 print(f"Closing client: {message}")
错误1:'ClientHandler' object is not callable
这个错误是错误2的连锁反应:因为装饰器被当成实例方法,类定义时调用__s_operation会把ClientHandler类本身作为self传入,导致func参数被错误覆盖,后续调用被装饰方法时相当于尝试调用类对象,自然触发"不可调用"错误。修复错误2后,该问题会自动解决。
关于私有属性/方法的访问
在类内部定义的装饰器(包括嵌套的check函数)可以正常访问实例的私有属性(如__is_dead)和私有方法。Python的双下划线名称修饰机制只是防止外部类/实例直接访问,同一个类内部的代码不受限制。
额外优化点
- 修正
__init__方法,补充c_ident参数传入逻辑 - 装饰器的
check函数添加**kwargs,兼容被装饰方法的关键字参数 - 被装饰方法有返回值时,
check函数需返回func(*args, **kwargs)的结果,否则调用方法会得到None
内容的提问来源于stack exchange,提问作者good user
相关产品推荐
相关产品推荐

