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

Python嵌套类变量访问规则及AttributeError报错咨询

Python类属性访问与结构体实现相关疑问

我是Python初学者,希望实现类似C++的类/结构体结构,但对Python的实际运行逻辑存在疑问,测试代码如下:

from dataclasses import dataclass

class innerClass:
    x: int


class outerClass:
    a: innerClass
    b: str
    c: str

test_1 = outerClass()

def setTest(val):
    global test_1
    test_1.x=val


def getTest():
    z=1
    global test_1
    if z==1:
        setTest(z)
    
    return [test_1.x]

getTest()

如果将z的值修改为z=0,则会出现如下报错:

Traceback (most recent call last):
  File "simplePy.py", line 27, in <module>
    getTest()
  File "simplePy.py", line 25, in getTest
    return [test_1.x]
AttributeError: 'outerClass' object has no attribute 'x'

具体疑问有两点:

  1. 为什么可以直接通过test_1.x访问x?按照outerClass->innerClass->variable的层级逻辑,我预期的访问方式应为test_1.a.x
  2. 当z=1时代码可正常运行,为什么z=0时会提示不存在x属性?我原本预期会返回无效值或0

解答

本质是你把Python的类型注解当成了C++的类成员声明,两者的运行逻辑完全不同:

  • 关于第一个疑问:你在类块中写的a: innerClass、b: str这类标注,只是给类型检查工具、代码编辑器看的类型提示,不会自动给类实例创建对应的属性。Python是动态类型语言,实例持有哪些属性完全由运行时的绑定操作决定,不需要提前在类中声明。
    你在setTest函数中执行test_1.x = val时,是直接给outerClass的实例test_1动态新增了一个名为x的属性,和类里定义的a: innerClass没有任何关联——你从头到尾都没给test_1绑定过a属性,自然也无法通过test_1.a.x的层级访问。
  • 关于第二个疑问:z=1时,代码会进入判断分支调用setTest,这一步刚好给test_1绑定了x属性,后续访问自然不会报错。
    把z改成0后,setTest函数根本不会执行,test_1从实例化到返回值的全流程中,从来没被绑定过x属性,访问不存在的属性必然抛出AttributeError。Python不会给未赋值的属性自动填充0、空值这类默认值,属性不存在就是不存在。

实现类似C++结构体的正确写法

你开头导入了dataclass但没有使用,这才是Python中实现类似C++结构体效果的标准工具,仅写裸类型注解不会生成任何实例属性,参考写法:

from dataclasses import dataclass

@dataclass
class InnerClass:
    x: int = 0  # 显式设置默认值

@dataclass
class OuterClass:
    a: InnerClass
    b: str = ""
    c: str = ""

# 实例化时显式给a属性赋值
test_1 = OuterClass(a=InnerClass())
# 此时访问逻辑完全符合你预期的层级结构
print(test_1.a.x)  # 输出0

内容的提问来源于stack exchange,提问作者Andrew Ahmos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:06:33