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'
具体疑问有两点:
- 为什么可以直接通过
test_1.x访问x?按照outerClass->innerClass->variable的层级逻辑,我预期的访问方式应为test_1.a.x - 当
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
相关产品推荐
相关产品推荐

