Python类嵌套调用异常:无法获取Duolingo活跃语言信息
问题分析与解决方案
你遇到的报错是因为嵌套类ActiveLanguage没有被实例化,直接通过类调用实例方法会缺少self参数。同时,要实现你想要的data.userdata.streak、data.activelanguage.name层级化访问形式,需要调整类的结构和属性定义方式。
修改后的代码方案(嵌套类版本)
import requests class DuoData: def __init__(self, username): self.username = username self.URL = "https://www.duolingo.com/2017-06-30/users?username={username}" self.data = requests.get(self.URL.format(username=self.username)) self.data_json = self.data.json() # 实例化嵌套的ActiveLanguage类,作为当前实例的属性 self.activelanguage = self.ActiveLanguage(self.data_json) @property def streak(self): return self.data_json['users'][0]['streak'] class ActiveLanguage: def __init__(self, data_json): self.active_language = data_json['users'][0]['courses'][0] @property def name(self): return self.active_language['title'] @property def xp(self): return self.active_language['xp'] @property def crowns(self): return self.active_language['crowns']
使用方式
# 初始化实例 duo = DuoData("your_username") # 层级化访问数据 print(duo.streak) # 获取连续学习天数 print(duo.activelanguage.name) # 获取活跃语言名称 print(duo.activelanguage.xp) # 获取活跃语言XP print(duo.activelanguage.crowns) # 获取活跃语言皇冠数
关键修改说明
- 实例化嵌套类:在
DuoData的__init__方法中,创建self.activelanguage属性,将嵌套类ActiveLanguage实例化后赋值给它,这样外部可以直接通过duo.activelanguage访问子对象。 - 使用
@property装饰器:把原来的get_xxx方法改成属性形式,实现直接通过.访问数据,符合你想要的层级化语法。 - 移除多余代码:删除
ActiveLanguage中不必要的super().__init__(),因为该类没有继承自定义父类,无需显式调用父类构造方法。
可选方案(拆分独立类)
如果不需要强绑定的嵌套结构,把ActiveLanguage拆成独立类会更清晰:
import requests class ActiveLanguage: def __init__(self, course_data): self.course_data = course_data @property def name(self): return self.course_data['title'] @property def xp(self): return self.course_data['xp'] @property def crowns(self): return self.course_data['crowns'] class DuoData: def __init__(self, username): self.username = username self.URL = "https://www.duolingo.com/2017-06-30/users?username={username}" self.data = requests.get(self.URL.format(username=self.username)) self.data_json = self.data.json() # 直接传入课程数据初始化ActiveLanguage self.activelanguage = ActiveLanguage(self.data_json['users'][0]['courses'][0]) @property def streak(self): return self.data_json['users'][0]['streak']
原报错原因
你之前调用duo.ActiveLanguage.get_name()时,ActiveLanguage是类对象而非实例对象,而get_name是实例方法——必须通过类的实例调用,Python才会自动传入self参数,因此触发了TypeError。
内容的提问来源于stack exchange,提问作者Infinibyte
相关产品推荐
相关产品推荐

