Python 中的模块和包有什么区别?

2024-12-20 08:37:00
admin
原创
79
摘要:问题描述:Python 中的模块和包有什么区别?另请参阅:“包”和“模块”之间有什么区别?(针对其他语言)解决方案 1:任何 Python 文件都是一个模块,其名称是文件的基本名称,不带.py扩展名。包是Python 模块的集合:模块是单个 Python 文件,而包是包含附加文件的 Python 模块目录,以...

问题描述:

Python 中的模块和包有什么区别?

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


解决方案 1:

  • 任何 Python 文件都是一个模块,其名称是文件的基本名称,不带.py扩展名。

  • 包是Python 模块的集合:模块是单个 Python 文件,而包是包含附加文件的 Python 模块目录,以区分包与恰好包含一堆 Python 脚本的目录。可以嵌套到任意深度,前提是相应的目录包含自己的文件。__init__.py`__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 编写的,但我认为你无意在问题中考虑这些。

解决方案 2:

模块是单个文件(或多个文件),在一次导入下导入并使用。例如

import my_module

包是目录中模块的集合,这些模块构成了包的层次结构。

from my_package.timing.danger.internets import function_of_love

模块文档

包简介

解决方案 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它不是一个包,因此不能有子模块。

您还可以在这里看到,包模块a具有__path__属性(包必须具有该属性),但非包模块a.b没有。

解决方案 4:

来自Python 词汇表:

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

名称中带有破折号的 Python 文件(如my-file.py)无法通过简单语句导入import。从代码角度来看,import my-file和 相同,这import my - file将引发异常。此类文件最好被描述为脚本,而可导入文件则是模块

解决方案 5:

这里的其他答案可能仍然有点模糊,所以我发布了一个希望更清晰的答案。重要的是要注意,问题的标题首先也有点误导,我认为更好的标题是:与常规模块相比,包模块有什么特别之处?

TL;DR——简短回答:

包也是模块,但它们是模块的一种特殊类型。特殊的含义是1.它们是“目录”;2.它们可能包含特殊文件,例如__init__.py__main__.py

为了更好地理解——更长的答案:

重点是,包是一种特殊类型的模块,因此我们需要首先了解模块的总体情况,然后才能理解包模块的特殊之处。(注意:我有时会将这个答案中的“包模块”简称为“包”,反之亦然)

因此,我们先来谈谈模块的一般情况,这样会比较清晰/容易理解。我们对模块基本上做两件事,要么将它们导入到其他模块中,要么直接通过 Python 执行它们。

导入模块有一个明显的目的,即访问模块内部的内容。

然而,执行模块通常追求以下两个目标之一:

  1. 该模块是一个主模块,执行它将启动我们的程序(或其子程序之一)。

  2. 我们希望单独尝试该模块的功能,即无需先导入它。

让我们通过一些例子来更好地理解这些:

导入模块:

# bar.py

def talk():
    print("bar")
# foo.py

import bar # <-- importing module "bar"

bar.talk() # <-- prints "bar"

执行模块

目标 1,将模块作为主模块执行:

假设foo.py上面例子中的模块是启动我们程序的主模块。我们可以通过在终端中输入此命令来运行它:python3 foo.py # <-- executing a main module然后它将启动我们的程序。

目标 2,单独尝试模块的功能:

假设我们想尝试上面示例中模块talk中的函数,而不运行整个程序,即不调用模块。为此,我们必须稍微改变:bar.py`foo.py`bar.py

# bar.py

def talk():
    print("bar")

if __name__ == '__main__':
    talk()

现在在终端中运行此命令:python3 bar.py # <-- trying functionalities of a module in isolation然后它将打印bar

现在我们知道了通常情况下模块能做什么,让我们回到主要问题:

与常规模块相比,包模块有何特殊之处?

1. Python 中的常规模块只是“文件”,而包模块则是“目录”。

2. 普通模块可以“导入”和“执行”(如上例所示),包模块也可以“导入”和“执行”,但是,你可能会抱怨:“但我们不能直接在目录中编写代码!代码只能写在文件中!”,这确实是一个很好的抱怨,因为它引出了包模块的第二个特殊之处。包模块的代码写在其目录内的文件中,这些文件的名称也是 Python 保留的。如果你想“导入”一个包模块,你必须把它的代码放在__init__.py其目录中的文件中,如果你想“执行”一个包模块,你必须把它的执行代码放在__main__.py其目录中的文件中。

以下是上述解释的最后一个例子:

# hierarchy of files and folders:
.
├── bar_pack/
│   ├── __init__.py
│   ├── __main__.py
│   foo.py
# bar_pack/__init__.py

def talk():
    print("bar")
# bar_pack/__main__.py

import __init__

__init__.talk()
# foo.py

import bar_pack # <-- importing package module "bar_pack"

bar_pack.talk() # <-- prints "bar"
# Run this command in the terminal:
python3 bar_pack # <-- executing the package module "bar_pack", prints "bar"

解决方案 6:

迟来的答案,还有另一个定义:

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

因此,从物理上讲,包是一个分发单元,它提供一个或多个模块。

解决方案 7:

模块:模块是一个简单的 Python 文件,带有 ( .py) 扩展名,其中包含函数和全局变量的集合。它是一个可执行文件,Python 中的包概念用于安排所有模块。

举例来说:将代码保存在名为 demo ( module.py) 的文件中。

def myModule1(name):
    print("My Module name is: "+ name)

导入演示模块module并使用其中的myModule1函数。

import demo_module
  
demo_module.myModule1("Math")

解决方案:

我的模块名称是:数学

包:包是一个包含模块集合的基本目录。此目录包含 Python 模块以及__init .py__解释器用来将其识别为包的 ( ) 文件。包只不过是一个命名空间。包内有子包。

举个例子:

学生(套餐)

| __init__.py(构造函数)

| details.py(模块)

| marks.py(模块)

| collegeDetails.py(模块)

| demo_module.py(模块)

包是一组组织到目录中的模块,以形成包目录。

from Student import details, collegeDetails, demo_module

解决方案 8:

我阅读了对这个问题的不同回答。这个问题已经完全涵盖了。但在我看来,再加一点可能不是一个坏主意。如果我们检查不同模块的package值,我们会得到以下结果。它们都是模块类型,但其中一些模块的包没有定义。检查package中是否有“ random ”和“ math ”。

import cv2
import math
import random
import tkinter as tk

print('cv2:',type(cv2))             # <class 'module'>
print('cv2:',cv2)                   # <module 'cv2.cv2' from 'PATH'>
print('cv2:',cv2.__package__)       # cv2

print('random:',type(random))       # <class 'module'>
print('random:',random)             # <module 'random' from 'PATH'>
print('random:',random.__package__) # [EMPTY]

print('tk:',type(tk))               # <class 'module'>
print('tk:',tk)                     # <module 'tkinter' from 'PATH'>
print('tk:',tk.__package__)         # tkinter

print('math:',type(math))           # <class 'module'>
print('math:',math)                 # <module 'math' (built-in)>
print('math:',math.__package__)     # [EMPTY]

如果我们定义一个文件夹如下:

在此处输入图片描述

我们可以看到__package__ 的输出如下:

import myfolder
import myfolder.script1 as s1
import myfolder.script2 as s2
import myfolder.mySubfolder.script3 as s3

print(type(s1)) # <class 'module'>
print(type(s2)) # <class 'module'>
print(type(s3)) # <class 'module'>

print(s1.__package__) # myfolder
print(s2.__package__) # myfolder
print(s3.__package__) # myfolder.mySubfolder

print(myfolder)                     # <module 'myfolder' (namespace)>
print(myfolder.mySubfolder)         # <module 'myfolder.mySubfolder' (namespace)>
print(myfolder.mySubfolder.script3) # <module 'myfolder.mySubfolder.script3' from 'PATH'>

print(myfolder.__package__)                     # myfolder        
print(myfolder.mySubfolder.__package__)         # myfolder.mySubfolder
print(myfolder.mySubfolder.script3.__package__) # myfolder.mySubfolder

解决方案 9:

下面简单说一下文档中模块和包中的内容:

  • 模块是一个文件或包(文件夹)。

  • 是一个可以有多个模块(文件和包(文件夹))的模块。

而且,这就是文档在模块中实际所说的内容:

  • 作为 Python 代码组织单元的对象。模块具有包含任意 Python 对象的命名空间。模块通过导入过程加载到 Python 中。

而且,这就是文档在下面的包中实际所说的内容:

  • 可以包含子模块或递归子包的 Python 模块。从技术上讲,包是具有路径属性的 Python 模块。

最后,您可以看到我的答案,解释如何创建模块(文件和包),您可以看到我的答案,解释如何为TestPyPI和PyPI创建、上传和安装包

解决方案 10:

我知道,已经太晚了,但对于一些人来说,一个简单的答案就足够了:

一个模块就是一个文件,

包就是一个文件夹。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1000  
  华为作为全球领先的信息与通信技术(ICT)解决方案提供商,其全球化项目的成功离不开高效的项目管理方法。其中,集成产品开发(IPD)流程是华为项目管理体系的核心组成部分。IPD流程不仅帮助华为在复杂的全球化项目中实现了资源的高效整合,还通过跨部门协作和持续优化,确保了项目的高质量交付。本文将通过具体案例,分析华为IPD流...
IPD测试流程   0  
  IPD(Integrated Product Development)是一种以跨职能团队协作为核心的产品开发流程,旨在通过整合资源、优化流程和提高决策效率,实现产品从概念到市场的快速、高效交付。IPD流程的核心思想是将传统的串行开发模式转变为并行开发模式,通过跨部门协作和早期风险识别,减少开发周期中的浪费和返工。这种方...
IPD流程分为几个阶段   0  
  华为的集成产品开发(IPD)流程是企业项目管理中的经典实践,其核心在于通过跨部门协同实现高效的产品开发。IPD流程强调从市场需求到产品交付的全生命周期管理,而跨部门沟通则是这一流程成功的关键。在华为的实践中,跨部门沟通不仅仅是信息的传递,更是团队协作、目标对齐和资源整合的重要手段。本文将深入探讨IPD流程中的跨部门沟通...
IPD项目管理咨询   0  
  IPD流程全称是集成产品开发(Integrated Product Development),它是一种以客户需求为导向、跨部门协作的产品开发模式。与传统产品开发模式相比,IPD强调在产品开发的早期阶段就整合市场、研发、制造、采购等多个部门的资源和能力,通过并行工程和协同工作来提升开发效率。IPD流程的核心在于打破部门壁...
IPD产品开发流程   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用