
本文讲解 python 类中因缩进错误导致方法不可访问的问题,重点修复 `apply_discount()` 方法因误嵌套在 `__init__` 中而引发的 `attributeerror`,并演示正确的类结构与折扣应用逻辑。
在面向对象编程中,方法定义的位置和缩进层级直接决定其作用域与可访问性。原代码中,calculate_total_price() 和 apply_discount() 两个方法被错误地缩进至 __init__ 方法内部,导致它们成为 __init__ 的局部函数,而非类的实例方法。因此,当调用 item1.apply_discount() 时,Python 在 Item 实例中找不到该属性,抛出 AttributeError: 'Item' object has no attribute 'apply_discount'。
正确做法是将所有实例方法与 __init__ 并列对齐(即同属类体一级缩进),确保它们绑定到类本身,可被所有实例调用。以下是修正后的完整代码:
class Item:
pay_rate = 0.8 # 类属性:统一折扣率(20% off)
def __init__(self, name: str, price: float, quantity=0):
# 参数校验
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater than or equal to zero!"
# 实例属性赋值
self.name = name
self.price = price
self.quantity = quantity
def calculate_total_price(self) -> float:
"""计算商品总价:单价 × 数量"""
return self.price * self.quantity
def apply_discount(self) -> None:
"""对当前实例的 price 属性应用类级折扣"""
self.price = self.price * Item.pay_rate
# 使用示例
item1 = Item("Phone", 100.0, 1)
print(f"折扣前价格: {item1.price}") # 输出: 100.0
item1.apply_discount()
print(f"折扣后价格: {item1.price}") # 输出: 80.0⚠️ 注意事项:
- 缩进即契约:Python 依赖缩进来定义代码块归属,类中所有方法必须与 __init__ 保持相同缩进(通常为 4 空格),否则会脱离类作用域;
- Item.pay_rate 是类属性,所有实例共享;若需为某实例设置独立折扣率,可改为 self.pay_rate 并在实例中赋值;
- apply_discount() 直接修改 self.price,属于“就地更新”。如需保留原价,建议新增 get_discounted_price() 方法返回新值,而非覆写原属性。
通过规范缩进与清晰的方法职责划分,即可安全、可维护地实现价格折扣逻辑。
立即学习“Python免费学习笔记(深入)”;










