Code前端首页关于Code前端联系我们

Python基础入门笔记:模块和包

terry 2年前 (2023-09-25) 阅读数 51 #后端开发

模块和包

2.1 模块

2.1.1 什么是模块

在Python中,文件称为模块。

我们研究过函数,知道函数就是实现一个或多个函数的程序。模块实际上是功能函数的扩展。为什么这么说?这是因为模块实际上是实现一个或多个功能的程序块。

根据上面的定义,不难看出函数和模块都是用来实现功能的,但是模块的范围比函数更广。一个模块中可以有多个函数。

模块的优点:

  • 使用模块最大的优点就是大大提高了代码的可维护性。当然,它也提高了代码的可重用性。
  • 使用模块还可以避免函数名和变量名冲突。具有相同名称的变量可以存储在不同的模块中。

    PS:但是请注意,变量的名称不能与内置函数的名称冲突。常用内置函数:直接链接

顺便扩展一下关于包的内容:

当编写的模块越多时,模块名称重复的概率就会增加。如何解决这个问题呢?

Python 引入了按目录组织的模块,称为包,例如:

extensions
├─ __init__.py
├─ dog.py
└─ cat.py
复制代码

Now dog.py 模块名称变为 扩展名❙

PS:请注意,在每个目录包将是文件 __init__.py。该文件是强制性的。否则,Python 会将该目录视为普通目录而不是包。地址簿。

如何使用套件中的模块?编写模块dog.py如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'jack guo'

import sys

def shout():
    args = sys.argv
    if len(args)==1:
        print('Hello, I'm afei, welcome to world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
   else:
        print('Yes,sir')

if __name__=='__main__':
    shout()
复制代码

说明:

第1行注释可以让dog.py文件直接在linux上运行;
第2行注释表示.py文件本身使用标准UTF-8编码;
第4行表示模块的文档注释;
第6行表示模块的作者;

注意最后两行代码,当我们调试dog.py时,shout()会调用,当在其他模块导入dog.py时,shout()不执行。
复制代码

模块的标准模板:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'jack guo'
复制代码

以上是模块的标准模板。当然,你不必这样做。 ? 导入数学 将数学模块导入到标准模块中。

无论您运行import多少次,该模块都只会导入一次。这可以防止导入的模块被一遍又一遍地执行。

Python解释器如何找到匹配的文件?

搜索路径:由一系列目录名组成。 Python 解释器按顺序从这些目录中搜索导入的模块。它看起来像环境变量。事实上,也可以通过定义环境变量来指定搜索路径。搜索路径是在编译或安装 Python 时确定的,并且在安装新库时也应进行修改。搜索路径存储在sys模块中的path变量中。可以打印:

import sys

print(sys.path)
复制代码

2.1.3 导入模块中的属性和方法,并调用方法

①导入模块

  • 导入模块名称
  • 导入模块名称为新名称 模块名称 导入函数名称 :在大型项目中应该避免使用这种方法,除非你完全确定它不会导致名称冲突;一个优点是您可以直接使用 function(),而无需添加 模块。函数()

PS1:导入模块并不意味着在导入过程中执行某些操作。它们主要用于变量、函数和类等定义。

PS2:可以使用命令 from ··· import * 导入模块中的所有方法属性。

②调用模块中的类和方法的变量、函数和属性

  1. module.variable
  2. module.function()
  3. module.class.variable

使用模块sys44的搜索路径2.1。 module)

(1) 程序所在目录

(2) 标准库的安装路径

(3) 操作系统环境变量 PYTHONPATH 指向的路径

  • 方法获取当前搜索路径Python:
    import sys
    print(sys.path)
    复制代码

    输出:

    ['D:\\workspace_pycharm', 'D:\\workspace_pycharm', 'D:\\python-practice', 'D:\\devInstall\\devPython\\Python36\\python36.zip', 'D:\\devInstall\\devPython\\Python36\\DLLs', 'D:\\devInstall\\devPython\\Python36\\lib', 'D:\\devInstall\\devPython\\Python36', 'D:\\devInstall\\devPython\\Python36\\lib\\site-packages']
    复制代码
  • sys模块argv变量用法:
    • sys模块有argv来存储所有变量值(参数)命令行。
    • argv 至少有一个元素,因为第一个元素始终是文件名 .py
    $ python solve.py 0    # 命令行语句
    # 获得argv变量的值
    sys.argv = ['solve.py', '0']
    sys.argv[0] = 'solve.py'
    sys.argv[1] = '0'
    复制代码

2.1.5 主模块和非主模块

在Python函数中,如果一个函数调用了其他函数来完成该功能,我们称这个函数为主函数。如果一个函数没有调用其他函数,我们称这个函数不是主函数。核心模块和非核心模块的定义也类似。如果一个模块被直接使用而没有其他人调用它,我们将该模块称为主模块。如果一个模块被其他模块调用,我们称该模块为非主模块。

如何区分主模块和非主模块?

可以使用属性__name__。如果属性值为 __main__ ,则该模块为主模块,反之亦然。但要小心:这个属性__main__只能帮助我们确定它是否是主模块。并不是说这个属性决定了它们是否是主模块。判断是否为主模块的唯一条件是该模块是否被调用过。 。像这样:

if __name__ == '__main__':
    print('main')
else:
    print('not main')
复制代码

如果输出结果是main,则该模块是主模块。

!!!附录:在第一次学习Python的过程中,总会遇到命令if __name__ == 'main'。让我们仔细看看。

先举个例子。假设A.py文件内容如下:

def sayhello():
    print('Hello!')
print('Hi!')
print(__name__)
复制代码

输出结果:

Hi!
__main__
复制代码

结果很简单,表示A.py文件本身运行时,变量__name__的值

__main__

有一个B.py文件,代码如下:

import A
A.sayhello()
print('End')
复制代码

可以看到B.py文件中导入了模块A,运行结果如下:

Hi!
A
Hello!
End
复制代码

这涉及到运行一些顺序问题命令。 .py文件中,模块A中的sayhello函数在调用时会被执行,但A中的print语句会立即执行(因为没有缩进,所以与def是并行级别的)。因此,首先执行:

print('Hi!')
print(__name__)
复制代码

,然后:

A.sayhello()
print('End')
复制代码

运算结果中Hello!对应模块print('Hello!')中的,结果A对应到 V print(__name__ ),可以看出,在文件 B 中调用模块 A 时,变量 __name__ 的值从 __ 变为 name模块A的。

好处是我们可以在A.py文件中进行多次测试,避免调用模块时的干扰。例如,将文件 A 更改为:

def sayhello():
    print('Hello!')
print('Hi!')
print(__name__)

if __name__ == '__main__':
    print('I am module A')
复制代码

再次单独运行 A.py 文件时,结果将是额外的 我是模块 A:

Hi!
__main__
I am module A
复制代码

但运行 B.py 文件时,这意味着在调用模块时不会出现此命令:

Hi!
A
Hello!
End
复制代码

简述:

模块属性__name__,其值由Python解释器设置。如果Python程序被称为主程序,则其值设置为__main__。如果它被其他文件作为模块导入,则其值为文件名。

每个模块都有自己的私有符号表,模块中定义的所有函数都使用它作为全局符号表。

2.2 包

2.2.1 什么是包

当我们编写自己的模块时,我们不必担心与其他模块的名称冲突。但是,请注意不要与内置函数名称冲突。但这里也有一个问题。如果不同人写的模块名相同怎么办?为了避免模块名称冲突,Python 引入了一种按目录组织模块的方法,称为包。

细心观察的人会发现,基本上每个包目录下都有一个文件__init__.py。该文件是必需的,否则Python会将此目录视为普通目录而不是包。 __init__.py可以是空文件,也可以是Python代码,因为__init__.py本身就是一个模块,对应的模块名称就是它的包名称。

2.2.2 包的定义和好处

  • Python 将 相似的模块 存储在一个文件夹中,以便统一管理。该文件夹称为 package
  • 如果把所有模块放在一起,显然很难管理,而且还有可能出现命名冲突。包
  • 实际上将模块存储到不同的类别中,然后告诉Python每个文件夹的位置。
  • Python 包根据 目录 组织成模块。他们还可以拥有多级目录来创建多级包结构。

2.2.3 创建包

  • 创建文件夹,用于存放相关模块。文件夹名称是包名称
  • 在文件夹中创建模块文件__init__.py。内容可以为空(常规文件夹和包之间的区别)。 ?文件夹,那么它是最好的选择:把它放在默认文件夹site-packages,因为它是用来存放你的模块文件的。
  • sys.path.append('模块存储位置') 仅在运行时生效,运行完成后失效。
  • 在用户系统环境变量中的PYTHONPYTH中添加保存包的路径,以便可以从任何地方调用包(推荐)。

②导入包中的模块

  1. 导入的包名称。模块名称
  2. 导入包名称。模块名称为新名称
  3. from模块导入功能包名称

③包中的模块。以及类属性和方法调用

  1. package.module.variable
  2. package.module.function()
  3. package.module.class.variable

2.3 范围 研究了 Java 众所周知, Java 类它们可以定义公共(public)或私有(private)方法和属性。这主要是因为我们希望某些功能和特性可以被其他人使用或者只能在内部使用。通过了解Python中的模块,它们实际上类似于Java中的类。那么我们如何实现模块中有些函数和变量被其他人使用而有些函数和变量只在模块内部使用呢?

在Python中是通过前缀_来实现的。普通函数和变量的名称都是公开的,可以直接引用,如:abcni12VARIsable‼️PI‼。 __xxx__ 是可以直接引用但有特殊用途的特殊变量。例如,上面的__name__是一个特殊变量,__author__也是一个用于识别作者的特殊变量。注意我们的自定义变量一般不会使用这样的变量名; 类似于 _xxx__xxx 此类函数或变量是私有的,不应直接引用,例如 、 __abc 等等。

注意:这意味着他不必这样做,而不是他不能。因为Python中没有办法完全限制对私有函数或变量的访问,所以出于编程习惯不应该引用私有函数或变量。

作者:Jaybo

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门