Python中函数内部定义类后如何从外部访问该类
函数内部类的外部访问实现
函数内部定义的类默认归属函数的局部命名空间,没有外部引用持有时,函数执行结束后类对象会随局部作用域被回收,外部无法直接访问。
此前尝试失效的原因
- 直接写
print(stuff.foo):stuff是genclass的局部变量,全局作用域没有对应标识符,会触发NameError。 - 写
print(genclass.stuff.foo):函数虽然是可挂载属性的一等对象,但你没有在函数执行流程中主动把内部类绑定为函数属性,函数对象上默认不存在stuff字段,会触发AttributeError。 - 写
print(genclass().stuff.foo):你定义的genclass没有显式返回值,默认返回None,None对象上不存在stuff属性,同样会触发AttributeError。
可正常运行的实现方案
方案1:直接返回内部类
最符合Python作用域设计的常规做法,把内部定义的类作为函数返回值传出,外部接收后即可正常使用:
#!/usr/bin/python3 def genclass(): class stuff: foo = 'Foo' bar = 'Bar' return stuff # 接收返回的类对象 MyStuff = genclass() print(MyStuff.foo) # 输出: Foo
方案2:将内部类绑定为函数的自定义属性
如果需要通过genclass.stuff的路径访问类,需要在函数内部主动把类赋值给函数自身的属性:
#!/usr/bin/python3 def genclass(): class stuff: foo = 'Foo' bar = 'Bar' # 给函数对象绑定自定义属性 genclass.stuff = stuff # 必须先调用一次函数,触发内部赋值逻辑 genclass() print(genclass.stuff.foo) # 输出: Foo
注意:如果跳过调用
genclass()的步骤,函数内部的赋值逻辑从未执行,函数对象上依然不存在stuff属性,会直接报错。
方案3:支持链式访问genclass().stuff的写法
如果需要实现此前尝试的链式访问效果,可以让函数返回一个持有类引用的容器对象:
#!/usr/bin/python3 from types import SimpleNamespace def genclass(): class stuff: foo = 'Foo' bar = 'Bar' # 返回挂载了类对象的简单命名空间 return SimpleNamespace(stuff=stuff) print(genclass().stuff.foo) # 输出: Foo
补充说明:每次调用
genclass时,内部定义的stuff类都会被重新创建,不同调用生成的类对象是相互独立的,修改某个类的属性不会影响其他调用生成的同结构类。
内容的提问来源于stack exchange,提问作者SkyyySi
相关产品推荐
相关产品推荐

