Python中如何动态以staticmethod方式调用类属性函数?
解决方案
方法1:子类中显式用staticmethod包装检查函数
如果子类用普通函数定义check,直接加@staticmethod装饰器;如果用lambda,用staticmethod()包装:
class MainMenuItem(MenuItem): @staticmethod def check(request): return request.user.is_authenticated # 或者用lambda实现 class AdminMenuItem(MenuItem): check = staticmethod(lambda request: request.user.is_superuser)
这样父类__init__中调用self.check(self.request)时,不会自动传入self——staticmethod会把函数转为非绑定状态,调用时只需要传入你指定的request参数。
方法2:父类__init__中自动处理绑定方法
如果不想让子类每次都手动加staticmethod,可以在父类初始化逻辑中,自动识别并处理绑定方法(即子类把check定义成实例方法的情况):
def __init__(self): self.request = ... check_func = self.check if callable(check_func): # 若为绑定方法(实例方法),取出未绑定的原始函数 if hasattr(check_func, '__func__'): check_func = check_func.__func__ self.check = check_func(self.request)
这样不管子类用哪种方式定义check,都不需要额外加self参数:
# 普通函数写法 class MainMenuItem(MenuItem): def check(request): return request.user.is_authenticated # 保持原lambda写法 class GuestMenuItem(MenuItem): check = lambda request: not request.user.is_authenticated
为什么你之前的尝试无效?
你用staticmethod(self.check)(self.request)的方式没用,是因为当self.check是实例方法时,它已经是绑定方法对象了——staticmethod包装绑定方法后,调用时依然会把self作为第一个参数传入,导致参数不匹配。而直接提取绑定方法的__func__属性,就能拿到不带绑定关系的原始函数,调用时只传request即可。
内容的提问来源于stack exchange,提问作者nerdoc
相关产品推荐
相关产品推荐

