Python中如何实现嵌套导入?直接导入对象内部成员的方法
嘿,这个好奇的问题问得挺好!先直接给你结论:你写的from foo import bar.childDef这种语法是不被Python支持的,会直接报语法错误,但我们有其他办法实现“直接用childDef()”的需求,具体得看bar到底是什么类型——是子模块/子包,还是模块里的类、对象?
分情况解决
情况1:bar是foo的子模块/子包
这是最理想的场景!如果你的目录结构是这样的:
foo/ __init__.py bar.py # 这里面定义了childDef函数
那完全可以用子模块导入的语法直接拿到childDef:
from foo.bar import childDef # 之后直接调用就行 childDef()
这种写法是Python原生支持的,本质上是把bar当作子模块来处理,和你一开始的思路很接近,只是语法上要把bar放到from后面的路径里。
情况2:bar是foo模块里的类/对象
如果bar是foo模块中定义的类、实例对象,或者是一个包含函数的字典这类结构,那没法直接在import语句里一步到位,但可以分两步(或者合并成一行)实现:
举个例子:bar是类,childDef是静态方法
假设foo.py里的代码是:
# foo.py class bar: @staticmethod def childDef(): print("我是childDef!")
你可以先导入bar,再把它的childDef属性赋值给全局变量:
from foo import bar childDef = bar.childDef # 直接调用 childDef()
嫌麻烦的话也可以合并成一行(虽然稍微有点小技巧,但完全合法):
from foo import bar; childDef = bar.childDef
如果childDef是类的普通实例方法,那要注意得先实例化bar再绑定方法,比如:
from foo import bar obj = bar() childDef = obj.childDef childDef()
进阶小技巧:让用户能直接from foo import childDef
如果你是foo模块的开发者,想让其他用户不用绕弯子直接导入childDef,可以在foo的__init__.py里提前把bar.childDef暴露出来:
# foo/__init__.py class bar: @staticmethod def childDef(): print("直接用我!") # 把childDef直接导出到模块级别 childDef = bar.childDef
这样用户只需要写from foo import childDef就能直接调用了~
为什么from foo import bar.childDef不行?
Python的from ... import ...语法规则里,import后面只能跟当前模块的直接成员,不能用点号去引用成员的嵌套属性——只有当点号前面的是子模块/子包时,才能把路径写到from后面(也就是我们第一种情况的写法)。
内容的提问来源于stack exchange,提问作者Zeeen

