You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:36:19