CS50P Jar类练习报错:构造函数传负容量未抛ValueError
问题分析与修复方案
你的代码核心问题是未对capacity的合法性做校验,同时部分方法的逻辑顺序错误,导致Check50检测失败。以下是具体修复点:
1. 给capacity添加合法性校验
当前的capacity setter直接赋值,没有判断传入值是否在0-12范围内。需要在setter中加入校验逻辑,确保构造函数传入负容量时抛出ValueError:
@capacity.setter def capacity(self, capacity): if not isinstance(capacity, int) or capacity < 0 or capacity > 12: raise ValueError("Capacity must be an integer between 0 and 12") self._capacity = capacity
2. 修正deposit方法的逻辑
你当前是先修改size再判断是否超限,会导致size先变成非法值再抛错,且硬编码12而非使用self.capacity,不符合类的封装设计。正确逻辑是先判断再修改:
def deposit(self, n): if not isinstance(n, int) or n < 0: raise ValueError("Deposit amount must be a non-negative integer") if self.size + n > self.capacity: raise ValueError("Too many cookies to deposit") self.size += n
3. 修正withdraw方法的逻辑
同理,你当前先减size再判断是否为负,会导致size先变成负数再抛错。正确逻辑是先判断再修改:
def withdraw(self, n): if not isinstance(n, int) or n < 0: raise ValueError("Withdraw amount must be a non-negative integer") if self.size - n < 0: raise ValueError("Not enough cookies to withdraw") self.size -= n
4. 给size添加合法性校验
为防止直接设置self.size时出现非法值,需在size的setter中加入校验:
@size.setter def size(self, size): if not isinstance(size, int) or size < 0 or size > self._capacity: raise ValueError("Size must be an integer between 0 and capacity") self._size = size
修复后的完整代码
class Jar: def __init__(self, capacity=12): self.capacity = capacity self.size = 0 def __str__(self): return '🍪' * self.size def deposit(self, n): if not isinstance(n, int) or n < 0: raise ValueError("Deposit amount must be a non-negative integer") if self.size + n > self.capacity: raise ValueError("Too many cookies to deposit") self.size += n def withdraw(self, n): if not isinstance(n, int) or n < 0: raise ValueError("Withdraw amount must be a non-negative integer") if self.size - n < 0: raise ValueError("Not enough cookies to withdraw") self.size -= n @property def capacity(self): return self._capacity @property def size(self): return self._size @capacity.setter def capacity(self, capacity): if not isinstance(capacity, int) or capacity < 0 or capacity > 12: raise ValueError("Capacity must be an integer between 0 and 12") self._capacity = capacity @size.setter def size(self, size): if not isinstance(size, int) or size < 0 or size > self._capacity: raise ValueError("Size must be an integer between 0 and capacity") self._size = size
关键说明
- 构造函数传入负容量时,会触发
capacitysetter的校验,抛出ValueError,满足Check50检测要求。 - 所有状态修改操作先做合法性判断,再修改值,避免对象处于非法状态。
- 不再硬编码12,而是使用
self.capacity,符合类的封装特性。
内容的提问来源于stack exchange,提问作者J Scott
相关产品推荐
相关产品推荐

