问题:Python模块和Python包之间有什么区别?

Python模块和Python包之间有什么区别?

另请参阅:“程序包”和“模块”之间有什么区别(对于其他语言)

What’s the difference between a Python module and a Python package?

See also: What’s the difference between “package” and “module” (for other languages)


回答 0

模块是在一个导入下导入并使用的单个文件。例如

import my_module

软件包是目录中提供软件包层次结构的模块的集合。

from my_package.timing.danger.internets import function_of_love

模块文档

套餐介绍

A module is a single file (or files) that are imported under one import and used. e.g.

import my_module

A package is a collection of modules in directories that give a package hierarchy.

from my_package.timing.danger.internets import function_of_love

Documentation for modules

Introduction to packages


回答 1

任何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>

在Python中,还有一些内置模块(例如)sys,这些模块都是用C语言编写的,但我认为您并不是要考虑问题中的那些模块。

Any Python file is a module, its name being the file’s base name without the .py extension. A package is a collection of Python modules: while a module is a single Python file, a package is a directory of Python modules containing an additional __init__.py file, to distinguish a package from a directory that just happens to contain a bunch of Python scripts. Packages can be nested to any depth, provided that the corresponding directories contain their own __init__.py file.

The distinction between module and package seems to hold just at the file system level. When you import a module or a package, the corresponding object created by Python is always of type module. Note, however, when you import a package, only variables/functions/classes in the __init__.py file of that package are directly visible, not sub-packages or modules. As an example, consider the xml package in the Python standard library: its xml directory contains an __init__.py file and four sub-directories; the sub-directory etree contains an __init__.py file and, among others, an ElementTree.py file. See what happens when you try to interactively import package/modules:

>>> 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>

In Python there also are built-in modules, such as sys, that are written in C, but I don’t think you meant to consider those in your question.


回答 2

Python词汇表中

重要的是要记住,所有软件包都是模块,但并非所有模块都是软件包。换句话说,包只是一种特殊的模块。具体来说,任何包含__path__属性的模块都被视为包。

名称中带有破折号的Python文件(如my-file.py)无法通过简单的import语句导入。代码明智的,import my-file是一样的import my - file,这将引发异常。这样的文件可以更好地描述为脚本,而可导入文件是模块

From the Python glossary:

It’s important to keep in mind that all packages are modules, but not all modules are packages. Or put another way, packages are just a special kind of module. Specifically, any module that contains a __path__ attribute is considered a package.

Python files with a dash in the name, like my-file.py, cannot be imported with a simple import statement. Code-wise, import my-file is the same as import my - file which will raise an exception. Such files are better characterized as scripts whereas importable files are modules.


回答 3

首先,请记住,按照其精确定义,模块是Python解释器内存中的对象,通常是通过从磁盘读取一个或多个文件来创建的。虽然我们可以非正式地称呼磁盘文件(例如a/b/c.py“模块”),但实际上它并没有与其他来自其他来源(例如sys.path)的信息组合在一起以创建模块对象,而是变成一个文件。

(例如,请注意,可以根据相同的sys.path设置和其他设置,从同一个文件中加载名称不同的两个模块。这正是在解释器中python -m my.module后面跟着的情况import my.module;将有两个模块对象,__main__并且my.module都创建了来自磁盘上的同一文件,my/module.py。)

是可以具有子模块(包括子包)的模块。并非所有模块都能做到这一点。例如,创建一个小的模块层次结构:

$ mkdir -p a/b
$ touch a/b/c.py

确保下没有其他文件a。启动Python 3.4或更高版本的解释器(例如,使用python3 -i)并检查以下语句的结果:

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'>

模块aa.b是程序包(实际上,一种程序包称为“命名空间程序包”,尽管我们在这里不必担心)。但是,模块a.b.c不是包。我们可以通过a/b.py在上面的目录结构中添加另一个文件并启动一个新的解释器来演示这一点:

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__'

Python确保在加载子模块之前先加载所有父模块。在其上方找到a/一个目录,因此创建了一个命名空间包a,这a/b.py是一个Python源文件,它被加载并用于创建(非包)模块a.b。此时,您无法拥有模块,a.b.c因为a.b它不是软件包,因此不能拥有子模块。

您还可以在此处看到package模块a具有__path__属性(packages必须具有此属性),但非package模块a.b则没有。

First, keep in mind that, in its precise definition, a module is an object in the memory of a Python interpreter, often created by reading one or more files from disk. While we may informally call a disk file such as a/b/c.py a “module,” it doesn’t actually become one until it’s combined with information from several other sources (such as sys.path) to create the module object.

(Note, for example, that two modules with different names can be loaded from the same file, depending on sys.path and other settings. This is exactly what happens with python -m my.module followed by an import my.module in the interpreter; there will be two module objects, __main__ and my.module, both created from the same file on disk, my/module.py.)

A package is a module that may have submodules (including subpackages). Not all modules can do this. As an example, create a small module hierarchy:

$ mkdir -p a/b
$ touch a/b/c.py

Ensure that there are no other files under a. Start a Python 3.4 or later interpreter (e.g., with python3 -i) and examine the results of the following statements:

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'>

Modules a and a.b are packages (in fact, a certain kind of package called a “namespace package,” though we wont’ worry about that here). However, module a.b.c is not a package. We can demonstrate this by adding another file, a/b.py to the directory structure above and starting a fresh interpreter:

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__'

Python ensures that all parent modules are loaded before a child module is loaded. Above it finds that a/ is a directory, and so creates a namespace package a, and that a/b.py is a Python source file which it loads and uses to create a (non-package) module a.b. At this point you cannot have a module a.b.c because a.b is not a package, and thus cannot have submodules.

You can also see here that the package module a has a __path__ attribute (packages must have this) but the non-package module a.b does not.


回答 4

一个较晚的答案,还有另一个定义:

包由导入的顶级实体表示,该顶级实体可以是一个独立的模块,也可以是__init__.py特殊模块,它是子目录结构中一组模块中的顶级实体。

因此,从物理上说,包装就是一个分配单元,它提供一个或多个模块。

A late answer, yet another definition:

A package is represented by an imported top-entity which could either be a self-contained module, or the __init__.py special module as the top-entity from a set of modules within a sub directory structure.

So physically a package is a distribution unit, which provides one or more modules.


回答 5

包也是一个模块,可以包含其他模块,“基于文件的简单模块和包(子包)”。与模块的包装类型相关的代码进入该__init__.py文件。

import pack1
print(type(pack1))

而模块是一个简单的文件,可以包含函数,类,可运行代码等。导入模块后,它的行为就像一个对象,您可以通过该对象访问模块中定义的标识符。

The Package is also a module that can contain other modules, ‘simple file-based modules, and packages (sub-package)’. The code related to the package type of module goes into the __init__.py file.

import pack1
print(type(pack1))

whereas modules are a simple file that can contain functions, classes, runnable code, etc. after importing a module it behaves like an object by which you can access the identifiers defined in the module.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。