Python类中使用Dataclass遇断言错误,求问题原因及解决
Python Dataclass 使用问题:断言错误分析与修复
问题重现
我正在学习Python,在使用Dataclass时遇到瓶颈。运行测试代码时出现断言错误,似乎无法正确识别Dataclass。相关代码如下:
业务代码(music_library.py)
from dataclasses import dataclass @dataclass class Track: title: str artist: str file: str class MusicLibrary: def __init__(self): self.track = Track def all(self): return self.track def add(self, title, artist, file): self.track(title = title, artist = artist, file = file)
测试代码
import unittest from player.music_library import MusicLibrary class TestMusicLibrary(unittest.TestCase): ml = MusicLibrary() def test_all(self): ml = MusicLibrary() ml.add("Track1", "artist1","file1") self.assertEqual(ml.all(), ["Track1","artist1","file1" ])
报错信息
Traceback (most recent call last): File "/projects/python/python-music-player-challenges/seed/tests/test_music_library.py", line 13, in test_all self.assertEqual(ml.all(), ["Track1", "artist1", "file1" ]) AssertionError: <class 'player.music_library.Track'> != ['Track1', 'artist1', 'file1']
错误原因
- 存储结构错误:
MusicLibrary的__init__方法中,self.track = Track是把类本身赋值给了属性,而非用来存储Track实例的容器(比如列表)。 - 实例未保存:
add方法仅创建了Track实例,但没有将这个实例添加到存储容器中,实例创建后直接被丢弃。 - 返回值不符合预期:
all方法返回的是Track类对象,而测试用例期望的是存储的曲目信息列表。 - 测试期望不匹配:测试用例期望返回字符串列表,但实际逻辑中应该返回
Track实例列表,或者从实例中提取对应属性组成列表。
修复后的代码
修正后的music_library.py
from dataclasses import dataclass @dataclass class Track: title: str artist: str file: str class MusicLibrary: def __init__(self): # 用列表存储Track实例,而非指向Track类 self.tracks = [] def all(self): # 返回存储的所有Track实例 return self.tracks def add(self, title, artist, file): # 创建Track实例并添加到列表中 new_track = Track(title=title, artist=artist, file=file) self.tracks.append(new_track)
修正后的测试代码
如果期望返回Track实例的列表,测试代码可修改为:
import unittest from player.music_library import MusicLibrary, Track class TestMusicLibrary(unittest.TestCase): def test_all(self): ml = MusicLibrary() ml.add("Track1", "artist1","file1") # 断言存储的是对应的Track实例 expected_track = Track("Track1", "artist1", "file1") self.assertEqual(ml.all(), [expected_track])
如果确实需要返回嵌套的字符串列表,可修改all方法:
def all(self): # 返回每个Track的属性组成的列表 return [[track.title, track.artist, track.file] for track in self.tracks]
对应的测试用例可保留原断言逻辑:
self.assertEqual(ml.all(), [["Track1","artist1","file1"]])
内容的提问来源于stack exchange,提问作者Gavin M
相关产品推荐
相关产品推荐

