Python学习笔记:第十四站 百宝箱

Python学习笔记


课程笔记参考B站视频: Python全栈开发教程


第十四站 百宝箱

本章介绍模块。

1. 什么叫模块

模块(Modules) 是比函数范围更广一层的概念,一个模块中可以包含多个函数、类、语句。在Python中一个扩展名为.py的文件就是一个模块。使用模块的好处有:

  1. 方便其它程序和脚本的导入并使用。
  2. 避免函数名和变量名冲突。
  3. 提高代码的可维护性。
  4. 提高代码的可重用性。

下图给出了这些概念囊括类型(注意一个Python程序可以包含多个包):

模块
函数
类属性
实例方法
实例属性
类方法
静态方法
语句

2. 自定义模块

创建模块的步骤就是 新建一个.py文件,注意名称尽量不要与Python自带的标准模块名称相同。导入模块的标准语法格式有以下两种:

'''方法一:导入整个模块'''
import 模块名称 [as别名]

'''方法二:导入模块的某个函数/变量/类'''
from 模块名称 import 函数/变量/[as 别名]

下面是导入整个模块的代码示例:

'''math是关于数学计算的一个模块'''
import math
print(id(math), type(math), math)
print(dir(math))
print('---------调用math中的变量、函数等----------')
print(math.pi)
print(math.ceil(9.98))
  • 运行结果
2740922946160 <class 'module'> <module 'math' (built-in)>
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 
'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 
'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 
'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 
'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 
'nan', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 
'tan', 'tanh', 'tau', 'trunc']
---------调用math中的变量、函数等----------
3.141592653589793
10

注:上述目录为手动换行。

下面是从模块中导入单个函数/变量/类的代码示例:

from math import pi
print(type(pi), pi)
print(math.pow(2,3))
  • 运行结果
<class 'float'> 3.141592653589793
8.0

注意单独导入的函数/变量等就不需要再加math.了。

下面演示如何自定义模块

  1. Pycharm中创建Python Package包文件夹,右键–>标记目录为–>Source Root。
  2. 在该包文件中创建Python文件calc.py,写入以下代码:
def add(a, b):
   return a+b
def mul(a, b):
   return a*b
  1. 新建一个文件。即可使用这个包中的模块:
import calc
print(calc.add(1.0, 2))
print(calc.mul(3, 1.2))
  • 运行结果为:
3.0
3.5999999999999996

3. 以主程序的形式执行

在每个模块的定义中都包括一个记录模块名称的变量_ _name_ _,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的_ _name_ _变量的值为_ _main_ _

上面这段翻译成人话就是,如果我在定义模块的文件中,也写了一些输出的语句,那么我在其他文件中调用这个模块时,会首先执行完模块中的输出语句,然后再执行其他的文件语句。这肯定不行啊,于是可以在定义模块的时候给所有的语句都加上下面这句限制条件:

if __name__ == '__main__':

含义就是只有当这个模块作为main文件的时候,才会运行if块里面的语句,否则不会运行,于是称之为“以主程序形式运行”。

下面是代码示例:

  • 模块文件:
def add(a, b):
   return a+b
def mul(a, b):
   return a*b

if __name__ == '__main__':
   print(add(10, 20))
   print(mul(10, 20))
  • 主文件:
import calc
print(calc.add(1.0, 2))
  • 运行结果1(加上以主程序运行的判定条件)
3.0
  • 运行结果2(不加判定条件)
30
200
3.0

4. python中的包

Python中的 包(Package) 是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下。作用是规范代码、避免模块名称冲突。与包相似的概念是 目录(Directory),它们的区别是:

  1. 包含_ _init_ .py文件的目录称为
  2. 目录里通常不包含_ _init_ _.py文件。

注:只要在目录中创建一个_ _main_ _.py文件,那么这个目录就立刻转换成包。

包的导入语法如下

import 包名.模块名 [as 别名]

from 包名 import 模块名 [as 别名]

最后切记:

  1. 使用import…方式进行导入时,只能跟包名或模块名
  2. 使用from…import…可以导入包,模块,函数,变量

下面是Python自带的一些常用的模块:

模块名描述
sys与Python解释器及其环境操作相关的标准库
time提供与时间相关的各种函数的标准库
os提供了访问操作系统服务功能的标准库
calendar提供与日期相关的各种函数的标准库
urllib(包)用于读取来自网上(服务器)的数据标准库
json用于使用JSON序列化和反序列化对象
re用于在字符串中执行正则表达式匹配和替换
math提供标准算术运算函数的标准库
decimal用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging提供了灵活的记录事件、错误、警告和调试信息等目志信息的功能

以上模块导入后都可以直接点开查看具体的函数有哪些。

下面是代码示例:

import sys
import time
import urllib.request
print('-----获取存储变量的内存大小(单位:字节)-----')
help(sys.getsizeof)
print(sys.getsizeof(12))
print(sys.getsizeof(23.6))
print(sys.getsizeof(True))
print(sys.getsizeof('嗯'))

print('-----使用time模块中的一些函数-----')
help(time.time)
print(time.time()) # 输出距离1970-01-01 00:00:00 UTC(Epoch)过去的秒数
print(time.localtime(time.time()))# 转换成年月日等时间

print('-----使用urllib包中的一些函数-----')
print(urllib.request.urlopen('http://baidu.com').read()) #.read()表示读取
# 哔哩哔哩要用post请求,而不是requests
  • 运行结果
-----获取存储变量的内存大小(单位:字节)-----
Help on built-in function getsizeof in module sys:

getsizeof(...)
   getsizeof(object [, default]) -> int
   
   Return the size of object in bytes.

28
24
28
76
-----使用time模块中的一些函数-----
Help on built-in function time in module time:

time(...)
   time() -> floating point number
   
   Return the current time in seconds since the Epoch.
   Fractions of a second may be present if the system clock provides them.

1657612783.7382038
time.struct_time(tm_year=2022, tm_mon=7, tm_mday=12, tm_hour=15, tm_min=59, tm_sec=43, tm_wday=1, tm_yday=193, tm_isdst=0)
-----使用urllib包中的一些函数-----
b'<html>\n<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">\n</html>\n'

5. 第三方模块的安装及使用

Python很强大,很大程度上也是因为第三方模块丰富多样。下面是第三方模块的安装语法(在线安装,最常用):

pip install 模块名

下面是安装schedule模块,这个模块主要用于计划:

  1. 配置环境变量:“我的电脑→属性→高级系统设置→环境变量→点击系统变量Path→编辑→新建→浏览放入python目录下的Scripts”。
  2. win+r输入cmd,然后输入pip install schedule即可。
  3. 若不想用windows命令行(也有可能在windoiws命令行安装完成后,依旧不能导入模块),直接在Pycharm最下面的终端(Terminal)安装即可。

安装完成后,第三方模块的使用语法如下:

import 模块名

下面是代码示例:

import schedule
import time

def job():
   print('哈哈哈...')

schedule.every(3).seconds.do(job)# 每3秒执行一次函数job
while 1:
   schedule.run_pending()  # 开始执行
   time.sleep(1)           # 休眠1秒

于是程序便可以每个3秒输出1次,然后休眠1秒,循环不止。

6. 本章作业

1. 模拟高铁售票系统

下面是代码示例:

import prettytable as pt
# 显示座席
def show_seat(row_num):
   table1 = pt.PrettyTable()
   # 定义标题
   table1.field_names = ['行号', '座位1', '座位2', '座位3', '座位4', '座位5']
   # 定义每一行
   for i in range(row_num):
       lst = [f'第{i+1}行', '有票', '有票', '有票', '有票', '有票']
       table1.add_row(lst)
   # 打印表格
   print(table1)

def order_ticket(row_num, row, column):
   tb = pt.PrettyTable()
   tb.field_names = ['行号', '座位1', '座位2', '座位3', '座位4', '座位5']
   for i in range (row_num):
       if int(row)==i+1:
           lst = [f'第{i + 1}行', '有票', '有票', '有票', '有票', '有票']
           lst[int (column)] = '已售'
           tb. add_row(lst)
       else:
           lst = [f'第{i + 1}行', '有票', '有票', '有票', '有票', '有票']
           tb.add_row(lst)
   print(tb)

if __name__ in '__main__':
   row_num = 13
   show_seat(row_num)
   order_ticket(row_num, 1, 1)
  • 运行结果
+--------+-------+-------+-------+-------+-------+
|  行号  | 座位1 | 座位2 | 座位3 | 座位4 | 座位5 |
+--------+-------+-------+-------+-------+-------+
|1|  有票 |  有票 |  有票 |  有票 |  有票 |
|2|  有票 |  有票 |  有票 |  有票 |  有票 |
|3|  有票 |  有票 |  有票 |  有票 |  有票 |
|4|  有票 |  有票 |  有票 |  有票 |  有票 |
|5|  有票 |  有票 |  有票 |  有票 |  有票 |
|6|  有票 |  有票 |  有票 |  有票 |  有票 |
|7|  有票 |  有票 |  有票 |  有票 |  有票 |
|8|  有票 |  有票 |  有票 |  有票 |  有票 |
|9|  有票 |  有票 |  有票 |  有票 |  有票 |
|10|  有票 |  有票 |  有票 |  有票 |  有票 |
|11|  有票 |  有票 |  有票 |  有票 |  有票 |
|12|  有票 |  有票 |  有票 |  有票 |  有票 |
|13|  有票 |  有票 |  有票 |  有票 |  有票 |
+--------+-------+-------+-------+-------+-------+
+--------+-------+-------+-------+-------+-------+
|  行号  | 座位1 | 座位2 | 座位3 | 座位4 | 座位5 |
+--------+-------+-------+-------+-------+-------+
|1|  已售 |  有票 |  有票 |  有票 |  有票 |
|2|  有票 |  有票 |  有票 |  有票 |  有票 |
|3|  有票 |  有票 |  有票 |  有票 |  有票 |
|4|  有票 |  有票 |  有票 |  有票 |  有票 |
|5|  有票 |  有票 |  有票 |  有票 |  有票 |
|6|  有票 |  有票 |  有票 |  有票 |  有票 |
|7|  有票 |  有票 |  有票 |  有票 |  有票 |
|8|  有票 |  有票 |  有票 |  有票 |  有票 |
|9|  有票 |  有票 |  有票 |  有票 |  有票 |
|10|  有票 |  有票 |  有票 |  有票 |  有票 |
|11|  有票 |  有票 |  有票 |  有票 |  有票 |
|12|  有票 |  有票 |  有票 |  有票 |  有票 |
|13|  有票 |  有票 |  有票 |  有票 |  有票 |
+--------+-------+-------+-------+-------+-------+

评论:我只想说这个程序很智障,只能定一次票。由于我在PrettyTable里面反复的查找,也没有看到直接获取某个元素的函数,只能说这个模块只能用于美化显示,而不是对元素进行修改等操作。理想的情况应该是将所有作为存成一个二维列表,所有的中间处理过程都在列表完成,只有最后显示的时候才使用PrettyTable。

思来想去,虽然骂爽了,但是自己不写点什么好像也说不过去,于是下面是代码示例:

import prettytable as pt
# 显示座席
def show_seat(seat_lst):
   table1 = pt.PrettyTable()
   # 定义标题
   table1.field_names = ['行号', '座位1', '座位2', '座位3', '座位4', '座位5']
   # 定义每一行
   for index,value in enumerate(seat_lst):
       lst = [f'第{index+1}行']
       lst.extend(value)
       table1.add_row(lst)
   # 打印表格
   print(table1)

# 初始化座位列表
def ini_seat(row_num):
   lst = []
   for i in range(row_num):
       lst.append(['有票', '有票', '有票', '有票', '有票'])
   return lst

# 订票
def order_seat(seat_lst, row, column):
   if seat_lst[row-1][column-1] == '已售':
       print('对不起,这个座位已售出!')
   else:
       seat_lst[row - 1][column - 1] = '已售'
   return seat_lst

if __name__ in '__main__':
   row_num = 13
   lst_seat = ini_seat(row_num)
   show_seat(lst_seat)
   while True:
       position = input('请输入座位的行列(如:13,1):')
       posi_lst = position.split(',')
       row = int(posi_lst[0])
       col = int(posi_lst[1])
       lst_seat = order_seat(lst_seat, row, col)
       con_judge = input('是否继续订票?y/n ')
       while con_judge!='n' and con_judge!='N' and con_judge!='y' and con_judge!='Y':
           con_judge = input('输入错误!是否继续订票?y/n ')
       show_seat(lst_seat)
       if con_judge=='Y' or con_judge=='y':
           continue
       else:
           print('感谢您的使用!')
           break

2. 推算今年几天后的日期

下面是代码示例:

import datetime
def inputdate():
   indate = input('请输入开始日期(如:20220707)后按回车:')
   indate = indate.strip() # 去掉前后的空格
   datestr = indate[0:4] + '-' + indate[4:6] + '-' + indate[6:]
   return datetime.datetime.strptime(datestr,'%Y-%m-%d')
if __name__ == '__main__':
   print('推算几天后的日期'.center(30,'-'))
   sdate = inputdate()
   in_num = int(input('请输入间隔的天数:'))
   fdate = sdate + datetime.timedelta(days=in_num)
   print('推算的日期是:' + str(fdate).split(' ')[0])
  • 运行结果
-----------推算几天后的日期-----------
请输入开始日期(如:20220707)后按回车:20220701
请输入间隔的天数:-1
推算的日期是:2022-06-30
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虎慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值