|
文章目录
- Python模块
- 模块之间的调用
- Python包
- 库的概念
- Python标准库
- 安装第三方库
- \_\_name\_\_ == '\_\_main\_\_'

Python模块
在 Python 中, 模块是一个包含函数、变量和类等代码定义的py文件.
所以也可以说, 普通的py文件就是一个模块.
模块可以被其他程序或模块导入, 并使用其中的代码.
一个模块可以包含多个函数、变量和类, 它们可以被其他程序重复使用, 提供了代码的可重用性和组织性.
使用模块的主要优势之一是代码的可重用性.通过将相关的代码组织在模块中, 可以在不同的程序或项目中重复使用, 减少代码重复编写的工作量, 并提高代码的可维护性和可扩展性.
Python 提供了许多内置的模块, 这些模块包含了丰富的功能和工具, 可以直接在代码中使用.例如, math
模块提供了数学运算函数, datetime
模块提供了日期和时间操作函数, random
模块提供了生成随机数等操作.
此外, 还有许多第三方模块可供使用.第三方模块是由独立的开发者或组织创建和维护的模块, 可以通过包管理工具如 pip
安装和导入到项目中, 提供了各种功能和扩展, 满足不同的需求.
项目开发的的代码文件,可能有成百上千个.
不同的代码文件,实现了不同的功能模块,就像一块块积木一样. 这些功能模块文件最后合起来,实现了一个完整的软件.
所以,在Python中,一个代码文件(也就是一个.py文件),我们也叫它一个模块(Module)
比如
a.py 文件,我们就可以称之为模块a
b.py 文件,我们就可以称之为模块b
模块之间的调用
导入模块
import math
导入后, 可以通过 module_name
来访问模块中的函数、变量或类. 例如, 使用 math
模块中的 sqrt
函数:
result = math.sqrt(16)
或者可以使用from-import来导入.可以选择性地导入模块中的特定函数、变量或类, 而不是导入整个模块.
from math import sqrt
# 或者可以一次性导入多个.
from math import sqrt, ceil
as可以为导入的模块或对象指定一个别名, 以便在代码中更方便地引用.
import math as m
result = m.sqrt(16)
导入全部, 不推荐使用
from math import *
# 可以导入math中全部的.
那么模块之间是怎么互相联系的呢?
我们来看一个例子:
几个同事午餐经常一起去饭店聚餐,我们开发一个程序,记录每人的账单,月末可以结算
我们可以把 输入总费用和聚餐人员,计算人均费用 的功能,单独实现在一个模块文件 aa.py, 其内容如下:
# aa.py
fee = input('请输入午餐费用:')
members = input('请输入聚餐人姓名,以英文逗号,分隔:')
# 将人员放入一个列表
memberlist = members.split(',')
# 得到人数
headcount = len(memberlist)
# 计算人均费用
avgfee = int (fee) / headcount
print(avgfee)
好了,人均费用计算比较简单.
但是我们还需要将每次账单 记录到文件中,这样才好定期结算.
我们可以创建另外的一个模块文件 save.py. 在里面定义一个函数, 该函数实现记录消费信息到文件功能. 其内容如下:
# save.py
def savetofile(memberlist, avgfee):
with open('record.txt','a',encoding='utf8') as f:
# 通过列表推导式,产生 人:费用 这样的列表
recordList = [f'{member}:{avgfee}' for member in memberlist]
f.write(' | '.join(recordList) + '\n')
注意: 目前我们把 save.py 和 aa.py 放在一个目录中
现在我们要在aa 模块里面使用save模块里面的函数 savetofile,该怎么做呢?
方法一
在aa.py里面 通过import关键字导入模块save ,
import save
这样save 就成了模块 aa 里面的的一个变量,这个变量指向的是一个 模块对象
不要感到奇怪,在Python中, 模块 也是一个对象.
这样我们就可以通过save.savetofile 访问到 save模块里面的函数
完整代码如下:
# 导入 save 模块
# 导入后 save 就成为模块aa中的一个变量,对应一个模块对象
import save
fee = input('请输入午餐费用:')
members = input('请输入聚餐人姓名,以英文逗号,分隔:')
# 将人员放入一个列表
memberlist = members.split(',')
# 得到人数
headcount = len(memberlist)
# 计算人均费用
avgfee = int(fee) / headcount
print(avgfee)
# 使用 模块save里面的 savetofile 函数
save.savetofile(memberlist, avgfee)
方法二
还可以在 aa.py 里面 通过 from import 关键字导入其它模块里面的标识符(包括变量名和函数名等).
导入之后,这些其它模块的变量名和函数名就成为 模块aa 里面 变量名,函数名了.
这样,我们就可以直接使用它们了.
完整代码如下:
# 从 save 模块 导入标识符 savetofile ,
# 导入后 savetofile 就成为模块aa中的一个变量,对应一个函数对象
from save import savetofile
fee = input('请输入午餐费用:')
members = input('请输入聚餐人姓名,以英文逗号,分隔:')
# 将人员放入一个列表
memberlist = members.split(',')
# 得到人数
headcount = len(memberlist)
# 计算人均费用
avgfee = fee / headcount
print(avgfee)
# 直接使用 savetofile 函数
savetofile(memberlist, avgfee)
__all__的作用
__all__
变量主要适用于在使用 from module_name import *
语句时, 控制模块中哪些标识符可以被导入.
当一个模块中定义了 __all__
变量时, 只有在 __all__
列表中列出的标识符才会被导入.其他未在 __all__
中列出的标识符将不会被导入.
这种机制可以用来控制通过 from module_name import *
导入的内容, 以避免意外地导入大量的标识符, 可能导致命名冲突或混乱的情况.
了解即可, 不推荐使用 from module_name import *, 容易导致命名冲突
Python包
实际开发中, 一个大型的项目往往需要使用到很多的Python模块, 如果将这些模块都堆放在一起, 势必不好管理.而且, 使用模块可以有效避免变量名或函数名重名引发的冲突, 但是如果模块名重复怎么办呢?因此, Python提出了包(Package)的概念.
python的包就是一个文件夹, 只是在该文件里包含了一个__init__.py
文件. 这个包里可以存放很多python的模块, 通过包, 在逻辑上将一批模块归为一类, 方便管理和使用.__init__.py
文件用来标识此文件夹是一个python包.
这些放模块文件的目录,Python中把他们称之为 包 (Package)
下面是一个商城产品目录结构的例子:
stock/ --- 顶层包
__init__.py --- stock包的初始化文件
food/ --- food子包
__init__.py
pork.py
beef.py
lobster.py
...
furniture/ --- furniture子包
__init__.py
bed.py
desk.py
chair.py
...
kitchen/ --- kitchen子包
__init__.py
knife.py
pot.py
bowl.py
...
最上层的是stock包,里面有3个子包 food、furniture、kitchen.
每个子包里面的模块文件都有名为stockleft的函数,显示该货物还剩多少件.
如果我们要调用这些模块里面的函数,可以像这样:
import stock.food.beef
# 注意导入的是 stock.food.beef,调用的时候一定要加上所有的包路径前缀
stock.food.beef.stockleft()
我们也可以使用from…import… 的方式,像这样
from stock.food.beef import stockleft
stockleft()
库的概念
如果你写的 模块文件 里面的函数, 实现了通用的功能,经常被其它模块所调用, 我们就可以把这些被调用的模块文件称之为 库
库是个抽象的概念,只要 某个模块 或者 一组模块 , 开发它们的目的 就是给 其它模块调用的,就可以称之为库.
Python标准库
Python语言提供了功能丰富的标准库. 这些标准库把开发中常用的功能都做好了。我们可以直接使用它们
这些标准库里面 有一部分叫做 内置类型(built-in types) 和 内置函数(built-in functions)
内置类型 和 内置函数 无须使用import导入,可以直接使用
内置类型有:int、float、str、list、tuple等
内置函数前面我们介绍过,可以在Python的官方文档查看到, 比如像 int,str,print,type,len 等等.
还有些标准库,需要使用import导入,才能使用
常见有 sys, os, time, datetime, json,random 等
比如,我们要结束Python程序,就可以使用sys库里面的exit函数
import sys
sys.exit(0)
比如,我们要得到字符串形式的当前日期和时间,可以使用datetime库
import datetime
# 返回这样的格式 '20160423'
datetime.date.today().strftime("%Y%m%d")
# 返回这样的格式 '20160423 19:37:36'
datetime.datetime.now().strftime("%Y%m%d %H:%M:%S")
比如,我们要获取随机数字,可以使用random库:
from random import randint
# 在 数字 1 到 8 之间(包括1和8本身),随机取出一个数字
num = randint(1,8)
print(num)
安装第三方库
Python 之所以这么流行,就是因为它有太多的优秀的第三方库和框架。
有了这些库,Python才能在各行各业都这么受欢迎。因为这些库极大的提高了开发效率。
要使用这些库,我们需要安装到本地。
在Python中,安装第三方库,通常是使用pip命令。
那些优秀的第三方库,基本都是放在一个叫 PYPI 的网站上
pip命令会从该网站下载这些库的安装包进行安装。
例如,如果我们要安装 requests库,可以执行如下的命令
pip install requests
我们在国内,使用pip 安装的时候,可能由于网络原因,到国外访问 PYPI 会比较慢。
而国内有网站(比如 百度/清华大学 等)对PYPI 做了镜像备份。
我们可以通过在命令中加上参数 -i https://pypi.tuna.tsinghua.edu.cn/simple ,这样就指定使用 清华大学源 作为安装包的下载网站。
如下所示:
# 使用清华大学源
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
注意: 如果你在公司使用代理上网,pip安装可能出现SSL证书校验错误,可以加上信任参数 --trusted-host ,如下所示
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
注意,很多初学者会在python shell里面执行pip命令,像这样
这个命令是一个程序,不是Python语句,要在cmd 命令行中直接执行,像这样
安装好以后,我们就可以使用import去导入这些库并且使用了
import requests
requests.get('http://www.baidu.com')
__name__ == ‘__main__’
用于确定当前模块是否作为主程序执行, 或者只是被导入到其他模块中使用.
__name__ 是什么?
在 Python 中,每个模块都有一个内置的属性__name__ ,它是一个字符串,用于标识模块的名称.
__name__ 的值取决于模块是如何被使用的:
-
作为主程序运行时
:
如果一个 Python 文件被直接运行(例如通过 python script.py),那么该文件的 __name__ 属性会被设置为 ‘__main__’. -
作为模块被导入时
:
如果一个 Python 文件被其他模块导入(例如通过 import script),那么该文件的 __name__ 属性会被设置为模块的名称(即文件名,不包括 .py 扩展名).
因此, 通过使用 if __name__ == '__main__'
条件判断, 可以实现以下效果:
- 当模块作为主程序执行时, 执行
if
语句块中的代码. - 当模块被导入到其他模块中时,
if
语句块中的代码将不会执行.
这种用法常用于在模块中定义一些测试代码, 以确保只有当模块作为主程序执行时才运行这些测试代码, 而在被导入时不执行.这样可以使模块在作为独立程序和作为库时具有不同的行为.
就是说: 自己写Python代码时在这个文件中实现了一些功能, 有时候我们会在这个代码的下方写一些调用的方法来测试代码, 这个时候可以把调用代码的部分写到 if __name__ == '__main__'
里面, 这样外部文件调用这个文件的时候就不会执行if语句里面用来测试执行代码的模块.
所以, __name__ == ‘__main__’ 的作用:
通过检查 __name__ 的值,可以判断当前模块是被直接运行,还是被其他模块导入. 这在编写代码时非常有用,因为它允许你为模块定义两种不同的行为:
- 直接运行时的行为:
当模块被直接运行时,可以执行一些初始化代码、测试代码或主程序逻辑. - 被导入时的行为:
当模块被其他模块导入时,可以避免执行某些代码,只提供函数、类或其他可复用的组件.
|
|