为什么__init__.py中要同时对__all__执行extend和append操作
Python包__init__.py代码解释
__all__的基础作用
Python中包的__all__变量用于声明包的公开导出接口,当第三方代码执行from 包名 import *语法时,只有__all__列表中登记的符号会被导入到当前作用域,未登记的符号默认不会被导入。
最后两行代码逐行说明
__all__.extend(apps.__all__)
extend()是列表的批量添加方法,会把传入的可迭代对象内的所有元素逐个追加到当前列表末尾- 这里的
apps.__all__是apps子模块自己声明的公开接口列表,这行代码的作用是把apps子模块对外暴露的所有接口,全部同步到当前父包的公开接口列表中。
举个例子:如果apps模块的__all__ = ['create_app', 'AppConfig'],执行完这行后,当前父包的__all__就会新增create_app、AppConfig两个元素,用户可以直接用from 父包 import create_app调用,不需要额外引入apps子模块。
__all__.append('apps')
append()是列表的单个元素添加方法,会把传入的内容作为一整个元素追加到列表末尾- 这里是把
apps子模块本身作为一个单独的公开符号加入父包的导出列表,执行完这行后,用户执行from 父包 import *时,也能直接拿到完整的apps模块对象,可以调用apps.create_app()这类写法。
同时使用extend和append的原因
两个方法的作用完全不重叠,分别适配不同的使用场景:
extend是为了简化调用路径,让用户可以直接在父包层级使用子模块的接口,不需要感知子模块的存在append是为了保留子模块的完整引用,满足需要直接操作子模块的场景
二者结合可以覆盖更多使用习惯,避免出现导入失败的问题。
内容的提问来源于stack exchange,提问作者kwaldner
相关产品推荐
相关产品推荐

