我无法弄清楚导入系统。为什么当我这样做时:
import os.path
然后我可以访问os.walk,它位于os,虽然我没有明确导入os?出于某种原因,这样的假动作不适用于它的package 。这是由于什么原因造成的?
更新
我知道 import 将导入的内容带入模块的命名空间。所以定义模块'myutils.py'c
import requests
在另一个模块中,得到如下图
import myutils
resp=myutils.requests.get('http://ya.ru') # работает
resp2=requests.get('http://ya.ru') # NameError: name 'requests' is not defined
os.path 中的 import os 机制是否有一些特殊性?我知道 os.path 是 os 的一部分,而不是 2 个完全独立的包,但我想确切地了解该机制。
在 Python 中导入结合了两个操作:
=)在搜索阶段(第 1 项)- 从规范-
import构造:也就是说,
import a.b.c导入 modulesa,a.b,a.b.c如果上述任何模块导入失败,则无法成功导入更嵌套的模块。在命名阶段(第 2 项):
import a.b.c在 Python 中,使a当前命名空间中的名称可用(例如,导入模块的全局命名空间a.b.c)并将属性:a.b和属性属性:分配a.b.c给适当的加载模块(类似于:a = sys.modules['a'];;a.b = sys.modules['a.b']..)。尽管这个问题很棘手,因为它
os不是 Python 包(__path__属性未设置)并且os.path是普通属性(与 相同os.walk),不同之处在于它os.path是一个模块并且os.py包含 hack:(sys.modules['os.path'] = path允许import os.path构造)。import os本身已经可以os.path在没有import os.path.使用更常规的示例改写问题:
import html.parser导入html和 (自然地)html.parser模块,并且由于html/__init__.py(在导入步骤中执行html)定义escape了一个函数,它html.escape()也可以像我们刚刚执行的那样使用import html。如果
module.nameafterimport module不起作用,那么这意味着您module/__init__.py没有定义name.旁白:性能
module.name不依赖于__all__.__all__公开名称的文档(正式名称可由 访问from module import *)以避免在不属于接口的每个名称前加上_(默认情况下类型名称从 中_name排除from module import *)。但这并不禁止显式引用如module._name(这应该避免,但如果你真的想要,你可以)。旁白:不要from module import *在 REPL 之外或__init__.py文件之外使用(合理使用示例:asyncio/__init__.py-asyncio提供“平面”公共接口(名称可直接用作asyncio.name),尽管实现分布在许多嵌套模块中) .只有显式导入才能导入
mypackage.mymodule_XXX和使用。mypackage.mymodule_YYY__init__.pymymodule_YYY假设您有一个包裹
mypackage:__init__.py:然后你可以在你的程序中做你想做的事:
至于
myutils。当您导入一个模块时,您只是将一个变量引入程序的命名空间,而不是引入一个myutils变量,因此它没有被定义是合乎逻辑的。requests一个变量myutils,它是一个模块,有自己的命名空间,有一个变量requests,所以myutils.requests你可以通过它访问它。当您导入 os.path 时,实际上导入了 os,显然 os 只是请求路径属性,这些导入不再发生
从 os 导入路径将是正确的