Python包管理机制

本文详细介绍了Python中的模块、主函数、非主函数、主模块和非主模块的概念,以及包的组织结构和import机制,包括相对导入和绝对导入的使用。此外,还强调了__name__变量在模块执行中的作用和如何在导入自定义模块时使用相对导入原则。
摘要由CSDN通过智能技术生成

一、模块

1、定义

模块中可以包含很多函数,python中的每一个python文件都可以作为一个模块,模块名就是python文件名

        在Python中,模块(Module)是一种组织代码的方式,它将相关的代码组织在一个单独的文件中,使得代码更易于管理、维护和重用。模块中可以包含函数、类、变量、甚至是可执行的代码,它提供了一种将代码逻辑划分为更小、更具体部分的方式。

让我们更详细地了解Python中的模块:

2、创建一个模块

要创建一个模块,只需在一个文件中编写代码,并使用.py作为文件扩展名。例如,创建一个名为my_module.py的模块:

# my_module.py

def say_hello(name):
    print(f"Hello, {name}!")

3、模块的命名空间

模块为您的代码提供了命名空间,这意味着您可以在不同模块中使用相同的名称,而不会产生冲突。例如,如果有两个模块都定义了名为function1的函数,您可以使用模块名来区分它们:

import module1
import module2

module1.function1()
module2.function1()

4、主函数与非主函数

        在Python中,了解主函数、非主函数、主模块、非主模块以及__name__变量的概念对于理解模块化编程和脚本的执行方式至关重要。

  • 主函数(Main Function):
    •  主函数通常是一个脚本中的入口点,是脚本的主要执行逻辑。它包含了程序的主要功能和算法。在Python中,函数并没有像一些其他编程语言那样强制性要求一个显式的主函数。
    • 任何在脚本中直接调用的代码都可以被认为是主函数。
  • 非主函数(Non-Main Function):
    • 非主函数是指在脚本中除了主函数之外的其他函数。它们可以作为主函数的辅助功能,被主函数调用。非主函数通常用于将代码分割为更小的可维护单元,提高代码的可读性和可重用性。

5、主模块与非主模块

  • 主模块(Main Module)
    • 主模块是指作为主脚本被直接执行的模块。在Python中,当一个脚本被作为主程序执行时,它被认为是主模块。主模块可以包含主函数,或者直接执行一些代码。
  • 非主模块(Non-Main Module)
    • 非主模块是指不作为主脚本直接执行的模块。它们通常是其他模块的依赖项,被其他模块导入和使用。非主模块可以包含函数、类、变量等,以供其他模块导入和重用。

6、主函数一定是在主模块中,非主函数一定在非主模块中

        通常情况下,主函数(Main Function)通常位于主模块(Main Module)中,而非主函数(Non-Main Function)通常位于非主模块(Non-Main Module)中。这是一种通用的组织代码的做法,有助于提高代码的可读性、可维护性和可重用性。

        主模块是指作为主程序直接执行的模块,它包含了主要的执行逻辑,可能包括主函数或直接执行的代码。主模块通常是脚本的入口点。

        非主模块是指不直接作为主程序执行的模块,它们被其他模块导入和重用。非主模块中可以包含函数、类、变量等,用于辅助主模块或其他模块的功能。

        尽管通常会遵循主函数在主模块中、非主函数在非主模块中的组织方式,但在实际开发中,有时也可以将主函数放在非主模块中,或者将非主函数放在主模块中,以满足特定的需求。这取决于项目的结构和设计。

        总之,主函数和非主函数的放置通常遵循一种有助于组织代码的模块化编程方式,但在一些特殊情况下也可以进行适当的灵活性调整。

7、main命令:__name__模块变量

python在执行import语句时会将文件(模块)中的代码时从上到下所有代码依次执行

使用情况:用于隐藏输出,只有在本文件内运行才会显示main下的代码输出,他人调用模块运行后没有main下代码的输出

__name__变量: 在Python中,每个模块都有一个名为__name__的特殊变量。__name__变量在不同的上下文中具有不同的值:

  • 当模块被作为主程序执行时,__name__的值为'__main__'。这意味着您可以使用if __name__ == '__main__':语句,来标识模块是否作为主程序运行。
  • 当模块被导入时,__name__的值为模块的名称(不包含.py后缀,和import语句后面导入的完整模块名有关)。这使得您可以检查模块是否被导入,并在需要时执行一些初始化操作。

下面是一个示例,演示了主模块、非主模块和__name__的使用:

假设有两个文件,main_module.py(主模块)和helper_module.py(非主模块)。

#Basic.主模块与非主模块.helper_module.py

def print_message():
    print("Hello from helper_module!")
    print("__name__的值为:",__name__)

print_message()

#Basic.主模块与非主模块.main_module.py

import Basic.主模块与非主模块.helper_module #完整模块名

def main():
    print("Hello from main_module!")
    Basic.主模块与非主模块.helper_module.print_message()
    print("__name__的值为:", __name__)

if __name__ == '__main__':
    main()
    """
    Hello from helper_module!
    __name__的值为: Basic.主模块与非主模块.helper_module
    Hello from main_module!
    Hello from helper_module!
    __name__的值为: Basic.主模块与非主模块.helper_module
    __name__的值为: __main__
    """

        在这个示例中,main_module.py是主模块,其中的main函数是主函数。helper_module.py是非主模块,包含一个print_message函数。

        当运行main_module.py时,__name__的值为'__main__',因此main()函数被执行。同时,helper_module.py中的代码也被导入和执行,但helper_module.print_message()只有在main()函数被调用时才会执行。

案例:

        总之,主函数、非主函数、主模块、非主模块以及__name__变量是Python中模块化编程和脚本执行方式的重要概念,有助于组织代码、实现模块的复用和调用,以及确定模块是作为主程序执行还是被导入和重用。

二、包(导入包时相当于导入该包的__init__.py文件)

1、定义

        在Python中,包(Package)是一个包含多个模块的目录,它允许您组织和管理相关的代码文件。包的概念有助于将代码分层组织,提高代码的可维护性和可复用性。

注意事项:

  • 包名应该是有效的标识符,遵循命名规范。
  • 模块和包的名称不应与Python标准库中的模块和包名称冲突
  • 考虑使用虚拟环境来隔离不同项目的包和依赖项。

使用包可以更好地组织和管理大型项目的代码,使代码结构更清晰,更易于维护。它还可以帮助您将代码模块化,以便在不同项目之间共享和重用。

2、创建一个包

起包名时不能和内置的模块重名

新建包:包名也属于标识符

要创建一个包,您需要创建一个包含一个名为__init__.py的空文件的目录。这个目录将作为包的根目录,可以在其中放置多个模块文件。例如,考虑一个名为my_package的包,其结构可能如下:

my_package/
|-- __init__.py
|-- module1.py
|-- module2.py

3、嵌套包

         Python允许您在包中创建嵌套包,即包中可以包含其他包。这有助于更好地组织代码和模块。例如,您可以在my_package包中创建一个名为sub_package的子包:

my_package/
|-- __init__.py
|-- module1.py
|-- module2.py
|-- sub_package/
|   |-- __init__.py
|   |-- module3.py
|   |-- module4.py

4、使用点语法访问子包中的模块

        通过点语法,您可以访问嵌套包中的模块。例如,要在module3.py中引用module1.py中的函数,可以这样做:

from my_package.sub_package import module3
from my_package import module1

result = module1.function1()

5、包中的__init__.py文件

__init__.py是一个特殊的文件,用于指示Python解释器将目录视为包。它可以包含初始化代码,也可以为空。当您导入一个包时,Python会首先执行该包中的__init__.py文件。

6、相对导入

在包内部,您可以使用相对导入来引用同一包中的其他模块。相对导入使用点语法,例如:

from . import module1

这将引用同一包中的module1模块。 

7、普通包和python包的区别

python包有一个init文件,可以将包当做模块使用

普通包就是一个文件夹

        在Python中,"普通包"通常是指不具备特殊功能的常规目录,而"Python包"指的是带有__init__.py文件的目录,用于组织和管理多个模块以形成一个代码库。下面我将详细解释这两种概念的区别。

普通包(Regular Directory): 普通包是指没有__init__.py文件的目录。这种目录可能包含一些Python模块文件,但由于缺少__init__.py文件,它不会被Python解释为一个包。因此,普通目录中的模块文件无法像从包中导入模块那样被导入(也可以正常导入,只不过导入包中的模块时,无法对包进行初始化操作)。普通目录中的文件仅仅是一个文件夹下的普通文件。

Python包(Python Package): Python包是指带有__init__.py文件的目录。这个文件夹可以包含一个或多个Python模块,它们可以被从包中导入。__init__.py文件本身也可以包含初始化代码,用于在导入包时执行一些操作。

Python包的结构如下:

my_package/
|-- __init__.py
|-- module1.py
|-- module2.py

        在这个示例中,my_package是一个Python包,其中包含了module1.pymodule2.py两个模块。通过导入my_package,您可以访问这些模块中的内容。

        总结: 普通包是没有__init__.py文件的目录,其中的文件无法被直接导入。Python包是带有__init__.py文件的目录,用于组织多个模块以形成一个可导入的代码库。通过使用Python包,您可以更好地组织、管理和重用代码,以及将代码模块化。

三、import机制

        在Python中,import语句用于导入其他模块或包中的代码,以便在当前模块中使用这些代码。import语句是Python中模块化编程的核心机制之一,它允许您将代码组织为不同的模块,以便更好地管理、维护和重用。

以下是关于import语句的详细解释:

1、基本导入语法

在Python中,使用import语句来导入其他模块或包。导入的基本语法如下:

  • import  模块名(适用于在同一个包中导入模块)
    • 使用:模块名.函数名()
  • from  模块名  import  函数名1,函数名2(适用于在同一个包中导入模块中的具体函数)
    • 使用:函数名()
  • import  包名.模块名1,包名.模块名2(适用于在不同包中导入模块)
    • 使用:包名.模块名.函数名()
  • from  包名  import  模块名(适用于在不同包中导入模块)
    • 模块名.函数名()

注意:

  • import后面跟谁就用谁,最终要到函数名;
  • java中有完整类名的概念,Python中也有完整模块名的概念
  • 只有import语句,则最小可导入到模块级别
  • 有from和import语句,则import语句最小可导入到函数级别
  • import后面导入的是模块,就必须全是模块,要是函数,就必须全是函数,不能混合,不能在import语句后面既有模块又有函数名
  • 包与模块连接‘.’ 语法(非相对导入)表示从属关系,翻译为:“的”;
  • 导入多个模块,类,函数,或变量使用逗号(,)隔开                                                
  • 快捷方法:Alt+回车:鼠标放在函数名上直接生成调用模块代码,在本文中可运行代码的上一行/小灯泡(注意:文件不能在script下,只能在venu下)

2、绝对导入

只是相对导入的一个特殊形式

        在Python中,模块之间的导入可以使用绝对导入和相对导入两种不同的语法。这两种语法用于在不同的上下文中管理模块的引用和导入。

        绝对导入是指从项目的根目录开始的完整模块路径。这种导入方式适用于直接导入项目中的模块或从项目的顶层模块开始导入。使用绝对导入时,你需要提供完整的模块路径,以确保导入的准确性。

例如,假设你的项目结构如下:

project/
|-- package1/
|   |-- module1.py
|-- package2/
|   |-- module2.py
|-- main.py

main.py中,使用绝对导入来导入module1的示例:

from package1 import module1

3、相对导入(Python中主要是相对导入 )

  1. from和import组合语句的导入默认为相对相对当前模块的位置,相当于加了“.”,但不能显示的加出来
  2. 只有import语句的导入默认为相对当前模块的位置,相当于加了“.”,但不能显示的加出来
  • 只能在包名前加 “ . ”来表示相对路径,模块不行,表示相对于当前模块的位置
    • 一般from后的包名前加 . 的这种语法只能出现在包的 __init__.py文件中,因为这种语法所写的地方自己本身就得是个包,不能是模块

        需要注意的是,相对导入在不同的Python版本和项目结构中的行为可能会有所不同。从Python 3.3开始,引入了一些关于相对导入的规则和改进,以提供更一致和可靠的导入行为。

        总之,绝对导入和相对导入都是用于在Python中管理模块导入关系的重要工具,但在使用时需要根据具体的情况选择适当的方式。

 4、包与模块连接点语法:(非相对导入)导入包中的模块

当要导入包中的模块时,可以使用点语法指定包和模块的路径。例如:

import package_name.module_name
from package_name import module_name

5、导入特定内容

您可以选择性地导入模块中的特定内容(函数、类、变量等)。这样可以避免在使用时使用模块名前缀。导入特定内容的语法如下:

from module_name import specific_content

6、重命名导入

您可以使用as关键字将导入的模块或内容重命名为其他名称。这在避免名称冲突或简化模块名时很有用。例如:

import module_name as alias
from module_name import specific_content as alias

7、通配符导入

虽然不推荐,但您也可以使用通配符导入整个模块的内容。这样做可能会导致命名冲突或代码不易理解,因此最好避免使用通配符导入。

from module_name import *

8、条件导入

您可以在需要时导入特定模块或内容,而不是在脚本的开头导入。这在某些情况下可以提高代码的性能。例如:

def some_function():
    import module_name
    # 使用module_name中的内容

9、导入顺序

Python会根据一定的搜索路径查找要导入的模块。

  • 首先,它会搜索内置模块,
  • 然后搜索已安装的第三方模块,
  • 最后搜索当前目录和其他指定的目录中的模块。

您可以使用sys.path查看Python的搜索路径。

10、python在执行import语句时会将文件(模块)中的代码时从上到下所有代码依次执行

python在执行import语句时会将文件(模块)中的代码时从上到下所有代码依次执行

11、注意事项:

  • 导入时要确保模块名或路径正确,以避免ModuleNotFoundError
  • 使用有意义的名称来重命名导入的内容,以提高代码的可读性。
  • 避免使用通配符导入,以避免可能的命名冲突和混淆。

        总之,import语句是Python中重要的语法,允许您在不同模块之间共享和重用代码。它是模块化编程的核心概念之一,有助于将复杂的代码拆分为更小、更易于管理的部分。

四、除内置模块外,使用import机制导入自定义的模块时必须全部使用相对导入原则

使用import机制导入自定义的模块时必须全部使用相对导入原则

因为Python中有完整模块名的概念,类似于java中的完整类名,若是在导入模块时部分是相对导入,部分是绝对导入,可能在某些比较的时候会有问题


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值