在计算机程序的开发过程中,随着程序代码越写越多,写在一个文件里的代码就会越来越长,越来越不容易维护。
为了让代码方便维护,我们将代码进行分类,分别放到不同的文件里。这样,所有的代码都按照一定的规则分布在各个文件里,需要使用的时候只要导入相应的文件即可。在 Python 中,这样的文件被称之为模块(Module)。
导入模块
当我们需要使用模块的时候,只需使用 import 语句导入对应的模块即可。
# other.py
print('带你打开编程世界的大门')
# main.py
import other # 导入 other 模块
# 输出:带你打开编程世界的大门
我们使用 import 模块名(不需要 .py 后缀)导入模块,相当于我们在 main.py 里借用并运行了 other.py 文件里的代码,因此运行结果是 带你打开编程世界的大门。你可以理解为 Python 会将 import other 语句替换成 other.py 里的代码。
import 语句还有一种用法是 import ... as ...,比如我们觉得 other 这个模块名太长,就可以用 import other as o,相当于给 other 取了一个别名为 o,之后我们就可以使用 o 来替代 other。数据分析常用的 pandas 和 numpy 常被简写成 pd 和 np,所以你会看到 import pandas as pd 和 import numpy as np 这样的写法。
导入部分模块
import 语句一次性将整个模块导入进来,我们还可以使用 from ... import ... 语句只导入我们需要的变量、函数等。
需要注意的是:使用 from ... import ... 的方式导入就不能再用 模块名.变量名 和 模块名.函数名 的方式访问模块内的变量或函数了,否则代码将会报错:
程序入口
当在做复杂项目的时候,我们会将代码拆分到各个模块中。这样,我们就需要一个程序入口,通过这个入口文件将整个项目的代码串联运行起来。
为了指明某个文件是程序入口,我们可以在代码中这样写:
# xxx.py
代码块 A
if __name__ == '__main__':
代码块 B
上面代码的意思是当 name 的值为 'main' 时执行代码块 B,那这里的 name 和 'main' 又都是什么呢?请听我慢慢道来:
其实 name 是 Python 里一个特殊的内置变量,它的值默认是模块名。而当文件被直接运行时,即通过命令行执行 python xxx.py 运行代码时,name 的值会被改为 main。
所以我们可以根据 name 的这个特性来判断模块是以导入的方式使用,还是作为程序入口文件直接运行,从而执行相对应的操作。比如只有作为程序入口执行时才运行启动程序的代码,否则什么都不做。
鸡兔同笼练习
鸡兔同笼问题是《孙子算经》中的经典题目,也是小学奥数题里的常客。
原书中是这么描述的:“今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?”
翻译成现代汉语就是:“鸡和兔放在一个笼子里,笼子里共有 35 个头,94 个爪,那鸡和兔各有多少只?”
请你根据下面的要求,用 Python 来完成这道数学题,和它一起“奥数”:
在 solution.py 中建立函数 calculate(),该函数能算出鸡和兔分别的数量;
在主程序 main.py 中导入函数 calculate(),根据题干中的“总头数”和“总脚数”输出问题的答案。
#solution.py
def calculate(heads,foots):
for x in range(1,heads):
y=heads-x
if 4*x+2*y==foots:
return x,y
#main
from solution import calculate
print('笼中有兔%d只,有鸡%d只' % calculate(35, 94))
内置模块 I
除了我们自己写的模块之外,Python 中还内置了大量非常实用的模块。
time 模块
# 导入time 模块
import time
# 暂停程序的执行,参数为秒
time.sleep(3) # 暂停 3 秒再执行后续代码
time.sleep() 这个方法它用于暂停程序的执行,参数为秒。它可以用于防止程序执行过快,比如爬取数据时降低爬取速率防止被封等。
import time
# 获取当前时间的 Unix 时间戳
print(time.time())
# 输出:1558329240.201314
Unix 时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒起至现在的总秒数。Unix 时间戳只是一个单纯不断增长的数字,所以不会存在时区等问题,全球统一,简单便捷。
Unix 时间戳对计算机来说稍微计算一下就知道现在是什么时间了,但对人类来说可读性就大打折扣了,所以还有对人类友好的 ctime() 方法:
import time
print(time.ctime())
# 输出:Mon Dec 07 13:09:20 2020
datetime 模块
datetime 模块包括很多函数和类,这些函数和类均用于日期和时间的解析、格式化以及计算。
# 导入 datetime 模块中的 datetime 对象
from datetime import datetime
# 获取当前时间
print(datetime.now())
# 输出:2019-05-20 13:14:00.201314
# 将 Unix 时间戳转换成时间
print(datetime.fromtimestamp(1558329240.201314))
# 输出:2019-05-20 13:14:00.201314
注意,datetime 模块里有一个同名的 datetime 类,因此我们要写成 from datetime import datetime。
datetime.now() 和 time.ctime() 类似,都是获取人类可读的时间格式,只是 datetime.now() 没有星期几的信息。
有些时候我们拿到 Unix 时间戳却不知道具体时间,可以使用 datetime.fromtimestamp() 方法来将其转换成人类可读的时间格式。
有些时候我们还要进行日期的计算,比如 5 天前是几月几号,10 天后又是几月几号等。这在 Python 中实现起来也不难,我们来看个例子:
from datetime import datetime, timedelta
print(datetime.now() - timedelta(days=5))
# 输出:2019-05-15 13:14:00.201314
timedelta() 在日期计算中很实用,上面代码中的 timedelta(days=5) 表示 5 天,用现在的时间减去 5 天就能得到 5 天前的日期。同理,如果加上 5 天就能得到 5 天后的日期了。
你应该注意到了,调用 timedelta() 时传的是关键字参数 days=5,表示 5 天。其实除了天之外,timedelta() 还支持传入周、时、分、秒、毫秒和微秒,timedelta() 可以支持同时传入多个参数。
内置模块 II
两个关于数字的模块
random 模块
# 导入 random 模块
import random
# 随机生成 0-1 之间的浮点数,包括 0,不包括 1
print(random.random())
# 输出:0.878022926133
# 随机生成 0-5 之间的整数,包括 0 和 5
print(random.randint(0, 5))
# 输出:3
# 随机生成 0-5 之间的浮点数,包括 0 和 5
print(random.uniform(0, 5))
# 输出:4.86369987147
# 从非空序列中随机返回一个元素
print(random.choice([1, 2, 3]))
# 输出:2
-
random.random() 可以生成 0-1 之间的随机小数,包括 0,不包括 1。这是最基本的生成随机数的方法,同时 random 模块还帮我们封装了一些更好用的方法——random.randint()、random.uniform() 和 random.choice()。
-
random.randint(m, n) 可以生成一个随机整数,该整数大于等于 m,小于等于 n。random.uniform(m, n) 也是类似的,只不过生成的是随机小数,该小数大于等于 m,小于等于 n。
-
random.choice() 可以从一个非空序列中随机返回一个元素,常常用于抽奖:
import random
winner = random.choice(['小贝', '小米', '小明'])
print('大奖得主是' + winner)
# 输出:大奖得主是小明
需要注意的是,参数一定得是非空序列,否则将会报错
- random.shuffle() 用于将序列的所有元素随机排序。
math 模块
- **random.shuffle()** 用于将序列的所有元素随机排序。
# 导入 math 模块
import math
# 向上取整
print(math.ceil(2.3))
# 输出:3
print(math.ceil(2.9))
# 输出:3
# 向下取整
print(math.floor(2.3))
# 输出:2
print(math.floor(2.9))
# 输出:2
# 取平方根
print(math.sqrt(4))
# 输出:2.0
# 数学常数 π
print(math.pi)
# 输出:3.14159265359
# 数学常数 e
print(math.e)
# 输出:2.71828182846
上面这些方法是比较常用的,同时 math 模块里还有很多其他方法和常数。对数学计算有需要的同学可以查看文档了解更多,文档地址是:https://docs.python.org/zh-cn/3/library/math.html。
练习
你肯定玩过“石头、剪刀、布”的游戏,学完了 random 模块后,我们来写一个 Python 版的“石头、剪刀、布”,然后和电脑玩一次“石头、剪刀、布”吧!
import random
choices = ['石头', '剪刀', '布']
#所有获胜的情形
win=[
['石头','剪刀'],
['剪刀','布'],
['布','石头']
]
your_choice = input('请输入石头、剪刀或布')
if your_choice in choices:
computer_choice=random.choice(choices)
if [your_choice,computer_choice] in win:
print("你出了%s,电脑出了%s,你赢了"%(your_choice,computer_choice))
if your_choice==computer_choice:
print("你出了%s,电脑出了%s,平局"%(your_choice,computer_choice))
else:
print("你出了%s,电脑出了%s,你输了"%(your_choice,computer_choice))
else:
print("输入有误")
网友评论