Dav*_*ave 511 python module package
Python模块和Python包之间有什么区别?
另请参阅:"package"和"module"之间的区别(对于其他语言)
Giu*_*lli 511
任何Python文件都是一个模块,它的名称是文件的基本名称而没有.py扩展名.甲包是Python模块的集合:而一个模块是一个Python文件,一个包是含有一个额外的Python模块的目录__init__.py文件中,一个包从恰好包含一堆Python脚本的一个目录区分开.如果相应的目录包含自己的__init__.py文件,则包可以嵌套到任何深度.
模块和包之间的区别似乎只适用于文件系统级别.导入模块或包时,Python创建的相应对象始终为类型module.但是,请注意,导入包时,只能__init__.py直接看到该包文件中的变量/函数/类,而不是子包或模块.例如,考虑xmlPython标准库中的包:其xml目录包含一个__init__.py文件和四个子目录; 子目录etree包含一个__init__.py文件,以及一个ElementTree.py文件.看看当您尝试以交互方式导入包/模块时会发生什么:
>>> import xml
>>> type(xml)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>> import xml.etree
>>> type(xml.etree)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>> import xml.etree.ElementTree
>>> type(xml.etree.ElementTree)
<type 'module'>
>>> xml.etree.ElementTree.parse
<function parse at 0x00B135B0>
Run Code Online (Sandbox Code Playgroud)
在Python中还有内置模块,例如sys,用C语言编写,但我认为你不打算考虑那些问题.
Jak*_*yer 331
模块是在一个导入下导入并使用的单个文件(或多个文件).例如
import my_module
Run Code Online (Sandbox Code Playgroud)
包是给出包层次结构的目录中的模块的集合.
from my_package.timing.danger.internets import function_of_love
Run Code Online (Sandbox Code Playgroud)
ade*_*hox 22
这里的其他答案可能仍然有点模糊,所以我发布了一个希望更清晰的答案。需要注意的是,问题的标题首先也有点误导,我认为更好的标题是:“与常规模块相比,包模块有什么特别之处? ”。
\n包也是模块,但是它们是模块的一种特殊类型。特殊是指1.它们是“目录”并且2.它们可能包含特殊文件,例如__init__.py和__main__.py。
重点是,包是一种特殊类型的模块,因此我们需要首先了解一般的模块,然后再了解包模块的特殊之处也就有意义了。(注意:我有时会在这个答案中将“包模块”称为“包”,反之亦然)
\n因此,让我们首先讨论一下一般的模块,因为它不会那么模糊/更容易理解。我们对模块基本上做了两件事,要么将它们导入到其他模块中,要么直接通过 Python 执行它们。
\n导入模块有一个明显的目标,即访问该模块内部的内容。
\n然而,执行模块通常会追求以下两个目标之一:
\n让我们通过一些例子来更好地理解所有这些:
\n# bar.py\n\ndef talk():\n print("bar")\nRun Code Online (Sandbox Code Playgroud)\n# foo.py\n\nimport bar # <-- importing module "bar"\n\nbar.talk() # <-- prints "bar"\nRun Code Online (Sandbox Code Playgroud)\n我们假设foo.py上面示例中的模块是启动我们的程序的主模块。我们可以通过在终端中输入以下命令来运行它:python3 foo.py # <-- executing a main module然后它将启动我们的程序。
假设我们想尝试上面示例中 moduletalk中的函数bar.py,而不运行整个程序,即不调用 module foo.py。为此,我们必须稍微改变bar.py:
# bar.py\n\ndef talk():\n print("bar")\n\nif __name__ == \'__main__\':\n talk()\nRun Code Online (Sandbox Code Playgroud)\n现在在终端中运行此命令:python3 bar.py # <-- trying functionalities of a module in isolation然后它将打印bar。
现在我们知道了一般可以用模块做什么,让我们回到主要问题:
\n__init__.py其目录中的一个文件中,如果你想“执行”一个包模块,你必须将执行代码它位于__main__.py其目录中的一个文件中。这是上述解释的最后一个示例:
\n# hierarchy of files and folders:\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar_pack/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py\n\xe2\x94\x82 foo.py\nRun Code Online (Sandbox Code Playgroud)\n# hierarchy of files and folders:\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar_pack/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py\n\xe2\x94\x82 foo.py\nRun Code Online (Sandbox Code Playgroud)\n# bar_pack/__init__.py\n\ndef talk():\n print("bar")\nRun Code Online (Sandbox Code Playgroud)\n# bar_pack/__main__.py\n\nimport __init__\n\n__init__.talk()\nRun Code Online (Sandbox Code Playgroud)\n# Run this command in the terminal:\npython3 bar_pack # <-- executing the package module "bar_pack", prints "bar"\nRun Code Online (Sandbox Code Playgroud)\n
Cur*_*son 18
首先,请记住,在精确定义中,模块是Python解释器内存中的对象,通常通过从磁盘读取一个或多个文件来创建.虽然我们可以非正式地调用诸如a/b/c.py"模块"之类的磁盘文件,但在与来自其他几个源(例如sys.path)的信息组合以创建模块对象之前,它实际上不会成为一个.(例如,注意,可以从同一文件加载具有不同名称的两个模块,具体取决于sys.path其他设置.)
甲包是可以具有子模块(包括子包)的模块.并非所有模块都能做到这一点.例如,创建一个小模块层次结构:
$ mkdir -p a/b
$ touch a/b/c.py
Run Code Online (Sandbox Code Playgroud)
确保下面没有其他文件python -m my.module.启动Python 3.4或更高版本的解释器(例如,with import my.module)并检查以下语句的结果:
import a
a ? <module 'a' (namespace)>
a.b ? AttributeError: module 'a' has no attribute 'b'
import a.b.c
a.b ? <module 'a.b' (namespace)>
a.b.c ? <module 'a.b.c' from '/home/cjs/a/b/c.py'>
Run Code Online (Sandbox Code Playgroud)
模块__main__和my.module包(事实上,某种类型的包被称为"命名空间包",虽然我们不担心这里).但是,模块my/module.py不是包.我们可以通过a在上面的目录结构中添加另一个文件并启动一个新的解释器来证明这一点:
import a.b.c
? ImportError: No module named 'a.b.c'; 'a.b' is not a package
import a.b
a ? <module 'a' (namespace)>
a.__path__ ? _NamespacePath(['/.../a'])
a.b ? <module 'a.b' from '/home/cjs/tmp/a/b.py'>
a.b.__path__ ? AttributeError: 'module' object has no attribute '__path__'
Run Code Online (Sandbox Code Playgroud)
Python确保在加载子模块之前加载所有父模块.在它上面发现它python3 -i是一个目录,因此创建了一个命名空间包a,它a.b是一个Python源文件,它加载并用于创建(非包)模块a.b.c.此时你不能拥有一个模块,a/b.py因为a/它不是一个包,因此不能有子模块.
您还可以在此处看到包模块a具有a/b.py属性(包必须具有此属性),但非包模块a.b不具有此属性.
小智 5
迟到的答案,还有另一个定义:
包由导入的顶级实体表示,该实体可以是独立的模块,也可以
__init__.py是作为子目录结构中一组模块中的顶级实体的特殊模块。
因此,从物理上来说,包是一个分发单元,它提供一个或多个模块。
| 归档时间: |
|
| 查看次数: |
189302 次 |
| 最近记录: |