从Python中的相对路径导入:奇怪的行为
据我所知,从
python docs开始,from package import x语句应该只将x,而不是package绑定到当前命名空间.
但实际上,如果包是一个相对的名字,它有时也受到约束! 让我举个例子.请考虑以下文件层次结构: root/ package/ __init__.py subpackage/ __init__.py 分装/ __ init__.py: foo = 42 包/ __ init__.py: from os import name from .subpackage import foo print(globals().get('name')) print(globals().get('os')) print(globals().get('foo')) print(globals().get('subpackage')) 现在让我们从根目录运行python(v2或v3)解释器并执行 >>> import package 前三条输出线是可预测的: posix None 42 但最后一个是< module'package.subpackage'...>而不是没有,这让我感到困惑. 我错过了什么吗?这是预期的行为吗?是什么原因? 在这种情况下,我的情况似乎更加奇怪: root/ __init__.py # Empty. package/ __init__.py another_package/ __init__.py another_package / __ init__.py: bar = 33 包/ __ init__.py: from ..another_package import bar print(globals().get('another_package')) 现在我在root之外运行它: >>> import root.package None # OK. >>> dir(root.package) ['__builtins__',...,'__path__','bar'] # OK. >>> dir(root) ['__builtins__','another_package','package'] # What?! 为什么another_package出现在dir(root)中? 解决方法
实现模块最多加载一次非常重要(除非它们明确地为
reloaded).如果在多个模块中导入模块,则所有模块引用相同的模块对象.例如.:
模块M.py bar = 10 模块A.py import M M.bar = 4 模块B.py import M M.bar = 6 所以: >>> import M >>> M.bar 10 >>> import A >>> M.bar # A is referencing the same M module object!! 4 >>> import B >>> M.bar # B is referencing the same M module object!! 6 现在,当执行..another_package导入栏中的语句时,它基本上等同于从root.another_package导入栏执行.由于another_package确实是root包中的一个模块,因此该语句会成功,并产生以下效果(可能会有更多,但为了这个目的,让我们关注这些3): >如果以前没有加载root,则加载root(运行’__init__.py’) 一些开发人员并不完全了解第1项和第3项. 回到你的问题:让我们看看在执行import root.package时会发生什么,顺序如下: > root的__init__.py运行(因为root还没有加载) 这解释了为什么another_package出现在root的目录中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |