python 模块和包

在这里插入图片描述

前言

Python是一种简单易学、功能强大的编程语言,而其模块和包的概念更是为我们提供了一种有效管理和组织代码的方式。模块是Python程序的基本组成单元,它是一个包含函数、变量和类的文件。而包则是由多个模块组成的一个目录,可以帮助我们更好地组织和复用代码。

在本系列的文章中,我们将从基础知识开始,逐步介绍Python模块和包的概念、语法和使用方法。

模块

什么是模块

在Python中,模块是一种组织和复用代码的方式。它是一个包含函数、变量和类的文件,以 .py 为文件扩展名。模块可以被其他程序导入和使用,以提供特定功能或实现特定任务。

Python模块使代码更易于管理和组织,同时也促进了代码的可重用性。通过将相关的功能放入不同的模块中,可以使代码更具可读性和可维护性。此外,模块还可以帮助开发人员对功能进行封装,以便在不同的项目中共享和复用代码。

导入模块

在 python 中,有以下的方式来导入模块:

  • import 模块名
  • from 模块名 import 功能名
  • from 模块名 import *
  • import 模块名 as 别名
  • from 模块名 import 功能名 as 别名

import 导入模块

前面我们也见过,当我们生成随机数的时候需要导入 random 模块,那么在 python 中可以使用 import 模块名 来导入模块。

当我们以 import 模块名 的形式导入模块的时候,使用 模块名.功能 来使用模块中的方法。

import random  # 导入random模块

result = random.randint(1,10)  # 生成1-9之间的随机数
print(result)

使用 import 模块名 也可以导入多个模块,但是不推荐 import 模块1,模块2...

from 模块名 import 功能

我们使用 import 模块名 导入的是该模块下的所有代码,我们也可以只导入该模块下的指定方法,并且我们调用方法的时候可以直接使用方法,而不需要加模块名。

from random import randint  # 导入random模块下的randint方法

result = randint(1,10)
print(result)

from 模块名 import *

from 模块名 import 功能from 模块名 import * 是相似的,只是前面一种导入方法,导入的是指定的功能,而后面一种方法导入的是该模块下的所有方法,两种导入方法调用功能的时候都只需使用功能() ,而不需要加上 模块名.功能。

from math import *

print(sqrt(9))  # 3.0
print(pow(3,2))  # 9.0

as定义别名

如果我们觉得模块名或者方法名太长写的时候太麻烦的时候,我们可以使用别名。
import 模块名 as 别名 来别名模块名,from 模块名 import 功能 as 别名 别名功能名。

import time as t
t.sleep(2)  # 程序会停止两秒再结束
from time import sleep as slp
slp(2)

当我们使用别名之后,之前的名字不能再继续使用,否则会报错

from time import sleep as slp
sleep(2)

在这里插入图片描述

制作模块

在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则。

我们创建一个 python 文件,并且在该文件中定义一个 add_num 方法。

在这里插入图片描述

我们可以对该模块内的 add_num 方法进行测试,看方法是否能实现指定功能。

def add_num(a,b):
    return a + b

print(add_num(1,2))  # 3

每实现一个模块中的方法,我们就需要进行测试,那么当我们测试完成之后,需不需要将测试代码给删除呢?如果不删除会有什么影响呢?

我们在 Test文件中导入该模块并使用该模块下的方法。
在这里插入图片描述
在这里插入图片描述

这里 3 很显然是我们测试代码里面的测试结果,import 模块名 会将该模块下的所有代码都导入,但是我们删除了测试代码的话,下次再测试又需要重新写,那我们该怎么做既能实现测试功能,又不影响其他功能呢?

使用 if __ name __ == '__ main __': 作为条件,来使该代码只会在该模块下执行,出来该模块所在的文件就不会执行测试代码。

__ name __ 是系统变量,是模块的标识符,值是:如果是自身模块,值是__ main __,否则是模块所在的文件名

我们在模块所在文件打印 __ name __。
在这里插入图片描述
在这里插入图片描述

然后在导入该模块的文件下运行代码。
在这里插入图片描述
在这里插入图片描述

我们在模块所在文件加上对应条件并执行代码。

def add_num(a,b):
    return a + b

if __name__ == '__main__':
    print(add_num(1,2))  # 3

然后在导入该模块的文件下调用该模块的对应方法。

import my_module1
print(my_module1.add_num(3,5))

在这里插入图片描述
在这里插入图片描述
这里并不会执行我们的测试代码,这样就解决了我们的问题。

注意:如果使用 from .. import ..from .. import * 导入多个模块的时候,且模块内有同名功能。当调用这个同名功能的时候,调用到的是后面导入的模块的功能。

from my_module1 import add_num
print(add_num(-3,5))  # 2

def add_num(a,b):
    return abs(a) + abs(b)
from my_module1 import add_num

def add_num(a,b):
    return abs(a) + abs(b)
print(add_num(-3,5))  # 8

模块的定位顺序

当导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前文件所在的目录下的所有文件
  2. 如果不在当前目录,python 则搜索在shell变量pythonpath下的每个目录
  3. 如果前面两个路径都找不到,python会查看默认路径

注意:

  • 自己的文件名不要和已有模块名重复,否则导致模块功能无法使用
  • 使用 from 模块名 import 功能 的时候,如果功能名字重复,调用到的是最后定义或导入的功能。

__ all __

但我们使用 from 模块名 import * 导入模块的时候,我们可以指定导入的方法,而不是全部方法,我们只需要在模块中定义 __ all __ = ['方法1',‘方法2'] ,这样就只会导入 __ all __ 中的方法。

__all__ = ['add_num']
def add_num(a,b):
    return a + b

if __name__ == '__main__':
    print(add_num(1,2))

def sub(a,b):
    return a - b

在这里插入图片描述

from my_module1 import *
print(sub(1,2))

在这里插入图片描述

这里会直接提示错误。
在这里插入图片描述

Python包是一种用于组织和管理Python代码的方式。它是一个包含模块、子包和资源文件的目录,可以在Python程序中被导入和使用。包的主要目的是将相关的功能和数据组织到一个单独的单元中,以便于重用和维护。

一个包通常包含一个名为 __init__.py 的特殊文件,用于标识该目录为一个包。它可以包含其他Python模块文件(以.py为扩展名)和子包(也是一个包的目录)。

在pycharm上如何创建包

在这里插入图片描述

当我们创建完成一个包之后,我们会发现该包下会自动产生一个 __ init __.py 的文件。

在这里插入图片描述

导入包

我们首先需要在包下创建几个模块文件。

add_num.py

def add_num(a,b):
    return a + b

sub_num.py

def sub_num(a,b):
    return a - b

导入包有两种方式:

  • import 包名.模块
  • from 包名 import *

import 包名.模块 导入包

当我们使用 import 包名.模块 导入包的时候,我们以 包名.模块名.功能 来使用相关功能。

import mypackage.add_num
import mypackage.sub_num
print(mypackage.add_num.add_num(10,20))  # 30
print(mypackage.sub_num.sub_num(50,20))  # 30

from 包名 import * 导入包

当我们使用 from 包名 import * 导入包的时候,我们需要在 __ init __.py 文件中添加 __ all __ = [ ] 来设置允许导入的模块列表。

__all__ = ['add_num','sub_num']

使用 模块名.功能 的方法来使用相应的功能。

from mypackage import *
print(add_num.add_num(10,20))  # 30
print(sub_num.sub_num(50,20))  # 30

如果我们将 __ init __ 文件中的 __ all __ = [ ] 给删除或者注释掉的话,会出现什么情况乱。
在这里插入图片描述
在这里插入图片描述
所以但我们使用 from 包名 import * 导入包的时候一定要记得设置 __ init __ 文件里的 __ all __ = [ ] 来设置允许导入的模块列表。

在这里插入图片描述