You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)   # 获取活跃语言皇冠数

关键修改说明

  1. 实例化嵌套类:在DuoData的__init__方法中,创建self.activelanguage属性,将嵌套类ActiveLanguage实例化后赋值给它,这样外部可以直接通过duo.activelanguage访问子对象。
  2. 使用@property装饰器:把原来的get_xxx方法改成属性形式,实现直接通过.访问数据,符合你想要的层级化语法。
  3. 移除多余代码:删除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:50:34