使用music21的partitionByInstrument拆分MIDI文件报错:NoneType无parts属性
解决music21中
instrument.partitionByInstrument返回None的AttributeError问题 嘿,我碰到过这个坑!咱们一步步把它搞定:
问题根源
你遇到的AttributeError: 'NoneType' object has no attribute 'parts',本质是instrument.partitionByInstrument()这个函数的特性导致的:它只有在MIDI文件的音轨里明确包含乐器类型的元数据时,才会返回带有parts属性的对象。如果你的MIDI是那种没有标记乐器信息的(比如很多老的简化和弦MIDI、自制简单MIDI),这个函数就会直接返回None——哪怕你已经确认song本身是存在音轨(parts)的。
快速修复方案
既然你已经通过song.show("text")确认了song里有parts,那我们只需要先判断partitionByInstrument的返回值是否为None,如果是的话直接用原song的parts就行:
from music21 import * song = converter.parse("/Nottingham/train/ashover_simple_chords_12.mid") print(len(song.parts)) # 输出2 parts = instrument.partitionByInstrument(song) # 先检查parts是否为None,避免触发报错 if parts is None: target_parts = song.parts else: target_parts = parts.parts # 现在可以正常访问音轨信息了 print(target_parts[0].id)
进阶:手动添加乐器元数据(如果需要按乐器分类)
如果你确实需要按乐器来划分音轨,可以手动给每个part注入乐器信息,这样partitionByInstrument就不会返回None了:
from music21 import * song = converter.parse("/Nottingham/train/ashover_simple_chords_12.mid") # 给每个音轨手动指定乐器(示例:第一个是钢琴,第二个是吉他) for idx, part in enumerate(song.parts): if idx == 0: part.insert(0, instrument.Piano()) else: part.insert(0, instrument.Guitar()) # 现在再调用partitionByInstrument就能正常返回结果了 parts = instrument.partitionByInstrument(song) print(parts.parts[0].id)
内容的提问来源于stack exchange,提问作者Konrāds Bušs
相关产品推荐
相关产品推荐

