如何修正Python中带参数的transpose装饰器以实现合法音符移调?
问题背景
音乐中的七个音符对应如下符号:
Note Symbol Do c Re d Mi e Fa f Sol g La a Si b
八度范围为1到7,示例格式如下:
"c1": 第1八度的Do, "d1": 第1八度的Re, "g1": 第1八度的Sol, "c2": 第2八度的Do, "a5": 第5八度的La.
现有预定义函数get_note(),返回音符+八度数字格式的字符串(比如d4)。需要实现一个带整数参数的装饰器transpose(n),用来调整音符的八度:
- 0:完全不修改
- 1:升高1个八度
- -3:降低3个八度
限制规则:调整后的八度不能低于1,也不能高于7。
调用示例:
from random import choice @transpose(2) # 传入八度调整参数 def get_note(): note = choice(['c', 'd', 'e', 'f', 'g', 'a', 'b']) octave = choice(range(1, 8)) print(f"Initial: {note}{octave}") return f"{note}{octave}" returned = get_note() print(f"result: {returned}")
示例1:
输入:d4,调整参数-3
输出:d1
示例2:
输入:c7,调整参数2
输出:c7
现有装饰器的问题
以下是我编写的transpose装饰器,存在多处错误:
def transpose(*args): def wrapper(func): print(*args) note, octode = func() octode = int(octode) print(octode) octode += int(*args) print(octode) return f"{note}{octode}" return wrapper @transpose def get_note(): ... # 函数逻辑,返回f"{note}{octode}"
需要修正的问题点
- 装饰器结构错误:带参数的装饰器需要三层嵌套结构,原代码仅两层,无法正确接收
@transpose(2)这类带参数的调用。外层函数应先接收调整参数,再返回装饰器函数,最后才是包裹原函数的执行逻辑层。 - 返回值拆分错误:
get_note()返回的是完整字符串(如d4),原代码直接用note, octode = func()拆分,会触发字符串拆包错误,需要手动分离音符字母和八度数字部分。 - 变量名拼写错误:多处将
octave(八度)拼写成octode,属于低级语法错误。 - 缺少范围限制:调整后的八度没有被约束在1-7之间,违反需求规则。
- 冗余调试代码:保留了不必要的
print语句,不符合生产代码规范。
修正后的装饰器实现
def transpose(shift): def decorator(func): def wrapper(): # 获取原函数返回的音符字符串 note_str = func() # 拆分音符字母与八度数字 note = '' octave_str = '' for char in note_str: if char.isalpha(): note += char else: octave_str += char octave = int(octave_str) # 计算新八度并限制在1-7范围内 new_octave = max(1, min(octave + shift, 7)) # 返回调整后的音符 return f"{note}{new_octave}" return wrapper return decorator # 测试用例 from random import choice @transpose(2) def get_note(): note = choice(['c', 'd', 'e', 'f', 'g', 'a', 'b']) octave = choice(range(1, 8)) print(f"Initial: {note}{octave}") return f"{note}{octave}" returned = get_note() print(f"result: {returned}")
修正说明
- 改为三层嵌套结构,完美支持带参数的装饰器调用;
- 通过遍历字符串拆分音符与八度,避免直接拆包报错;
- 使用
max(1, min(...))强制约束八度范围,符合需求规则; - 修正变量名拼写错误,移除冗余调试代码。
内容的提问来源于stack exchange,提问作者Albina Hakobyan
相关产品推荐
相关产品推荐

