Python如何编写作用于类方法的装饰器实现下注资金校验
问题核心原因
你的装饰器运行报错、逻辑不生效是两个低级错误导致的:
- 作用域错误:实例方法被调用时,类实例本身会作为第一个位置参数传入,但你在wrapper函数里没有正确接收这个参数,直接凭空引用作用域里不存在的
self变量,自然会抛出NameError: name 'self' is not defined。 - 参数取值和判断逻辑错误:
args[0]实际是类实例本身,不是你传入的下注金额,而且你写的大小判断逻辑完全反向,就算self不报错也走不对校验分支。
正确实现方案
这个装饰器直接定义在类外部即可,这种通用校验逻辑放在类外复用性更强,没必要写在类内部增加冗余。
第一步:编写正确的资金校验装饰器
wrapper函数可以显式把self作为第一个参数接收,比硬取args[0]可读性更高:
def check_funds(func): def wrapper(self, bet_amount, *args, **kwargs): # 校验下注金额是否超过账户可用余额 if bet_amount > self.funds: return "You do not have the funds to place this bet" # 校验通过才执行原下注逻辑 return func(self, bet_amount, *args, **kwargs) return wrapper
第二步:给下注方法加上装饰器
只需要在place_bet方法定义上方加@check_funds注解即可:
class User: """Creates a user betting account""" def __init__(self, first_name, last_name, username, age, funds, city): self.first_name = first_name self.last_name = last_name self.username = username self.age = age self.funds = funds self.city = city @check_funds def place_bet(self, amount): self.funds -= amount return f"{self.first_name.title()} - You have placed a £{amount} bet. You have £{self.funds} remaining."
效果验证
直接运行测试代码即可确认功能正常:
# 初始化一个余额为100镑的测试用户 test_user = User("Scott", "Butler", "scottb", 30, 100, "London") # 下注30镑,余额充足 print(test_user.place_bet(30)) # 输出:Scott - You have placed a £30 bet. You have £70 remaining. # 下注100镑,余额不足 print(test_user.place_bet(100)) # 输出:You do not have the funds to place this bet
适配扩展
如果后续你需要让这个装饰器兼容更多带金额参数的类方法,可以不把bet_amount写死在wrapper参数列表里,从可变参数里取值即可,适配性更强:
def check_funds(func): def wrapper(self, *args, **kwargs): # 约定所有被装饰的方法,第一个位置参数为交易/下注金额 amount = args[0] if amount > self.funds: return "You do not have the funds to place this bet" return func(self, *args, **kwargs) return wrapper
这种写法和显式声明参数的写法效果完全一致,如果装饰器只给place_bet单个方法用,显式写参数的写法更易维护。
内容的提问来源于stack exchange,提问作者ScottMButler
相关产品推荐
相关产品推荐

