PYTHON1.day13
day12回顾:
函数装饰器
作用:
在不改变函数的定义及函数调有和的情况下为函数或类
添加功能或修改功能
语法:
def 装饰器函数名(fn被装饰函数):
创建闭包函数
def fx(...):
...
return 闭包函数
@装饰器函数名
def 被装饰函数名(形参列表):
语句块
函数的文档字符串:
def fa():
'''这是文档字符串'''
fa.__doc__
help(fa) # 查看文档字符串
函数的 __name__ 属性
绑定函数的名称
def 函数名():
pass
语法:
[装饰器1]
[装饰器2]
[...]
def 函数名(位置形参, *args, 命名关键字形参, **kwargs):
....
模块 Module
包含有数据,函数,类等组成的程序组
math.pi # 数据
math.sin(0) # 函数
模块的导入语句(import 语句)
三种:
import 模块名 [as 模块新名], 模块名2, ...
from 模块名 import 属性名 [as 属性新名], 属性名2....
from 模块名 import *
数学模块 math
时间模块 time
系统模块 sys
模块的种类:
1. 内建模块
2. 标准库模块
3. 第三方模块
4. 自定义模块
day13 笔记
自定义模块
要求:
1. 模块文件后缀名必须以.py结尾
2. 模块文件名必须是合法的标识符
3. 避免名称和内建模块名冲突
导入方式:
import 语句
from import 语句
from import * 语句
示例见:
mymod.py
test_mymod.py
1 # mymod.py 2 3 '''这是自定义模块mymod标题 4 5 此模块共有两个函数和两个数据如下: 6 .... 此处省略字 7 ''' 8 9 10 # 此示例示意自定义一个mymod模块 11 def myfac(n): 12 '''这是求阶乘的函数的文档字符串''' 13 print("正在计算%d的阶乘" % n) 14 15 def mysum(n): 16 print("正在计算1+2+3+...+%d的和" % n) 17 18 name1 = 'audi' 19 name2 = 'tesla' 20 21 print("mymod模块被加载") 22 23 print("mymod.py 模块内的__name__属性绑定的是:", __name__) 24 25 26 27
1 # test_mymod.py 2 3 4 # 此示例示意调用自定义的mymod.py 模块内的两个函数和两个字符串 5 6 import mymod # 导入自定义模块 mymod.py 7 8 mymod.myfac(5) # 调用自定义模块的函数 9 mymod.mysum(100) 10 11 print(mymod.name1) # 获取mymod里的name1绑定的字符串 12 13 from mymod import name2 14 print(name2) # tesla 15 16 from mymod import * 17 myfac(20) 18 mysum(1000) 19 20 print("test_mymod.py里的__name__属性的值是:", __name__) 21 # __name__ = '__main__'
1 # test_mymod.py 2 3 4 # 此示例示意调用自定义的mymod.py 模块内的两个函数和两个字符串 5 6 import mymod # 导入自定义模块 mymod.py 7 8 import copy 9 import pdb 10 11 name1 = "小张" # 模块内全局,不会和 mymod里的name1冲突 12
import 语句搜索模块的路径顺序:
1. 搜索内建模块
2. 搜索程序运行时的路径(当前工作目录)
3. 搜索sys.path提供的路径
sys.path是一个列表,里面放的都是模块的索引路径
模块化编程的优点:
1. 有利于多人合作开发
2. 使代码更加易于维护
3. 提高代码的复用率(模块可以被其它代码或者模块使用)
4. 模块化编程有助于解决变量名冲突(重名)问题,模块内的全局变量的
作用域为模块内全局
模块的加载过程
在模块被导入时,模块的所有语句会执行
如果一个模块已经被导入,则再次导入时不会重新执行模块内的语句
模块的重新加载
import mymod
import imp
imp.reload(mymod) # 重新加载mymod模块
模块被导入和执行的过程:
1. 先搜索相关路径找模块(.py)
2. 判断是否有此模块对应的.pyc文件,如果.pyc文件比.py文件新
则直接加载.pyc文件
3. 否则用模块.py 文件生成.pyc文件并加载执行
模块的编译 compile
编译 解释执行
mymod.py -------> mymod.pyc --------> python3
模块的文档字符串
模块内第一个没有赋值给任何变量的字符串是文档字符串
模块的__doc__属性
用于绑定模块的文档字符串
模块的 __file__属性
__file__ 用于绑定模块文件的路径名
注:
内建模块没有__file__属性
模块的 __name__ 属性
__name__属性用来记录模块自身的名字
作用:
1. 记录模块名
2. 用来判断是否为主模块
说明:
1. 当此模块作为主模块(也就是第一个运行的模块)运行
时,__name__ 绑定 '__main__'
2. 当此模块不是主模块,而是被其它模块导入时,__name__绑
定模块名
模块的 __all__ 列表
模块中的__all__列表是一个用来存放可导入属性的字符串列表
作用:
当用from xxx import *导入时,只导入 __all__列表内的属性
示例见:
mymod2.py
1 # mymod2.py 2 3 4 # 此示例示意__all__列表在模块中的应用 5 # __all__列表只能影响 from import *语句,其它语句不受限制 6 7 __all__ = ['f1', 'name1'] 8 9 def f1(): 10 f2() 11 f3() 12 pass 13 14 def f2(): 15 pass 16 17 def f3(): 18 pass 19 20 name1 = 'aaa' 21 name2 = 'bbb' 22 23 24 25 26 27
模块的隐藏属性:
模块中以下划线(_)开头的属性,在from xxx import * 导入时
将不被导入, 通常称这些属性为隐藏属性
作用:
限制from import *语句,不导入隐藏属性
示例见:
mymod3.py
1 # mymod3.py 2 3 # 此示例示意模块的隐藏属性,当此模块用from import * 语句导 4 # 入时,不会导入 _f, __f, 和 _name 属性 5 6 def f(): 7 pass 8 9 def _f(): 10 pass 11 12 def __f(): 13 pass 14 15 name = 'aaa' 16 _name = 'bbb' 17
随机模块 random
作用:
用于模拟随机输出
文档参见:
python_base_docs_html/随机模块random.py
随机模块 random
说明:
random模块是用于模拟或生成随机输出的模块.
import random as R
函数名
描述
R.random()
返回一个[0, 1) 之间的随机实数
R.uniform(a,b)
返回[a,b) 区间内的随机实数
R.randrange([start,] stop[, step])
返回range(start,stop,step)中的随机数
R.choice(seq)
从序列中返回随意元素
R.shuffle(seq[, random])
随机指定序列的顺序(乱序序列)
R.sample(seq,n)
从序列中选择n个随机且不重复的元素
R.getrandbits(nbit)
以长整型的形式返回用nbit位来表示的随机数
R.seed(a=None)
用给定的数a设置随机种子,不给参数a则用当前时间设置随机种子
练习:
1. 猜数字游戏:
随机生成一个0~100之间的整数,用变量x绑定
让用户循环输入一个整数,用变量y绑定,输出猜数字的结果
如果y等于x,则提示'恭喜您猜对了',并结束猜数字
如果y大于x,则提示:'您猜大了'
如果y小于x,则提示:'您猜小了'
直到猜对为止,显示用户猜数字的次数后退出程序
1 # guess_number.py 2 3 # 练习: 4 # 1. 猜数字游戏: 5 # 随机生成一个0~100之间的整数,用变量x绑定 6 # 让用户循环输入一个整数,用变量y绑定,输出猜数字的结果 7 # 如果y等于x,则提示'恭喜您猜对了',并结束猜数字 8 # 如果y大于x,则提示:'您猜大了' 9 # 如果y小于x,则提示:'您猜小了' 10 11 # 直到猜对为止,显示用户猜数字的次数后退出程序 12 13 14 import random # 首先导入自己 15 16 x = random.randint(0, 100) # x=random.randrange(101) 17 18 # print(x) 19 20 count = 0 21 22 while True: 23 y = int(input("请输入整数: ")) 24 count += 1 25 if y == x: 26 print("恭喜您猜对了") 27 break 28 elif y > x: 29 print("您猜大了") 30 else: 31 print("您猜小了") 32 33 print("您共猜了%d次" % count)
包(模块包) package
包的定义
包是将模块以文件夹的组织形式进行分组管理的方法
作用:
将一系列模块进行分类管理,有利于访问命名冲突
可以在需要时加载一个或部分模块,而不是全部模块
包示例:
mypack/
__init__.py
menu.py
games/
__init__.py
contra.py
supermario.py
tanks.py
office/
__init__.py
word.py
excel.py
包的导入:
同模块的导入规则:
import 包名 [as 包别名]
import 包名.模块名 [as 模块新名]
import 包名.子包名.模块名 [as 模块新名]
...
from 包名 import 模块名 [as 模块新名]
from 包名.子包名 import 模块名 [as 模块新名]
from 包名.子包名.模块名 import 属性名 [as 属性新名]
...
from 包名 import *
from 包名.模块名 import *
...
import 语句 搜索包的路径顺序
1. 搜索程序运行时的路径(当前工作路径)
2. sys.path提供的路径
包的 __init__.py 文件
__init__.py 是常规包内必须存在的文件
__init__.py 会在包加载时被自动调用
作用:
编写此包的内容
在内部填写包的文档字符串
示例见:
mypack/__init__.py
__init__.py 内的 __all__ 列表
作用:
用来记录此包中有哪儿些子包或模块需要导入
当用 from 包 import * 语句导入模块时,只查找__all__中
所有的模块或子包
说明:
__all__ 列表只在from xxx import * 起作用
示例见:
mypack/games/__init__.py
包的相对导入
包的相对导入是指包内模块的相互导入
语法:
from 相对路径包或模块 import 属性或模块名
或
from 相对路径包或模块 import *
相对路径:
在from import 语句和from import *语句中可以使用相对导入
在 from 和 import 间可以用相对路径
. 代表当前目录(文件夹)
.. 代表上一级目录
... 代表上二级目录
.... 以此类拟
注: 相对导入时不能超出包的外部
示例见:
mypack.games/contra.py 里的gameover函数
练习:
1. 随机生成6位密码:
可以作为密码的字符有:
a-z, A-Z, 0-9
随机生成一个6位的密码
1 # 1. 随机生成6位密码: 2 # 可以作为密码的字符有: 3 # a-z, A-Z, 0-9 4 # 随机生成一个6位的密码 5 6 import random 7 8 charator = [chr(x) for x in range(65, 65+26)] 9 charator += [chr(x) for x in range(97, 97+26)] 10 charator += [str(x) for x in range(10)] 11 12 # print(charator) 13 passwd = '' 14 for _ in range(6): 15 passwd += random.choice(charator) 16 17 print("密码是:", passwd) 18 19
2. 模拟斗地主发牌,牌共54张
种类:
黑桃('\u2660'), 梅花('\u2663'), 方块('\u2665'),
红桃('\u2666')
数字:
A2-10JQK
王牌: 大小王
三个人,每人发17张牌,底牌留三张
输入回车,打印第1个人的17张牌
输入回车,打印第2个人的17张牌
输入回车,打印第3个人的17张牌
输入回车,打印3张底牌
1 # test_mymod.py 2 3 4 # 此示例示意调用自定义的mymod.py 模块内的两个函数和两个字符串 5 6 import mymod # 导入自定义模块 mymod.py 7 8 mymod.myfac(5) # 调用自定义模块的函数 9 mymod.mysum(100) 10 11 print(mymod.name1) # 获取mymod里的name1绑定的字符串 12 13 from mymod import name2 14 print(name2) # tesla 15 16 from mymod import * 17 myfac(20) 18 mysum(1000) 19 20 print("test_mymod.py里的__name__属性的值是:", __name__) 21 # __name__ = '__main__'
3. 将学生信息管理程序拆分为模块
要求:
1. 主事件循环放在main.py中
2. show_menu函数放在menu.py中
3. 写学生操作相关的函数放在student_info.py中
1 # file : menu.py 2 3 4 def show_menu(): 5 '''显示菜单''' 6 print("+--------------------------------+") 7 print("| 1) 添加学生信息 |") 8 print("| 2) 显示学生信息 |") 9 print("| 3) 删除学生信息 |") 10 print("| 4) 修改学生成绩 |") 11 print("| 5) 按学生成绩高-低显示学生信息 |") 12 print("| 6) 按学生成绩低-高显示学生信息 |") 13 print("| 7) 按学生年龄高-低显示学生信息 |") 14 print("| 8) 按学生年龄低-高显示学生信息 |") 15 print("| q) 退出 |") 16 print("+--------------------------------+") 17 18
1 # file: student.py 2 3 def input_student(): 4 L = [] # 创建一个列表,准备存放学生数据的字典 5 while True: 6 n = input("请输入姓名: ") 7 if not n: # 如果用户输入空字符串就结束输入 8 break 9 a = int(input("请输入年龄: ")) 10 s = int(input("请输入成绩: ")) 11 d = {} # 一定要每次都创建一个新的字典 12 d['name'] = n 13 d['age'] = a 14 d['score'] = s 15 L.append(d) # 把d加入列表中L 16 return L 17 18 def output_student(L): 19 print("+---------------+----------+----------+") 20 print("| 姓名 | 年龄 | 成绩 |") 21 print("+---------------+----------+----------+") 22 for d in L: 23 name = d['name'] 24 age = str(d['age']) # 转为字符串 25 score = str(d['score']) # 转为字符串 26 print("|%s|%s|%s|" % (name.center(15), 27 age.center(10), 28 score.center(10))) 29 print("+---------------+----------+----------+") 30 31 def delete_student(L): 32 name = input("请输入要删除学生的姓名: ") 33 i = 0 # i 代表列表的索引 34 while i < len(L): 35 d = L[i] # d绑定字典 36 if d['name'] == name: 37 del L[i] 38 print("删除", name, "成功!") 39 break 40 else: 41 print("删除失败!") 42 43 def modify_student_score(L): 44 pass 45 46 47 def output_by_score_desc(L): 48 def get_score(d): 49 return d['score'] 50 L2 = sorted(L, key=get_score, reverse=True) 51 output_student(L2) 52 53 def output_by_score_asc(L): 54 L2 = sorted(L, key=lambda d:d['score']) 55 output_student(L2) 56 57 def output_by_age_desc(L): 58 L2 = sorted(L, key=lambda d:d['age'], reverse=True) 59 output_student(L2) 60 61 def output_by_age_asc(L): 62 L2 = sorted(L, key=lambda d:d['age']) 63 output_student(L2) 64 65 66 67 68
1 # file : main.py 2 3 from menu import show_menu 4 from student_info import * 5 6 def main(): 7 infos = [] # 此列表用于保存学生数据 8 while True: 9 show_menu() 10 s = input("请选择: ") 11 if s == '1': 12 infos += input_student() 13 elif s == '2': 14 output_student(infos) 15 elif s == '3': 16 delete_student(infos) 17 elif s == '4': 18 modify_student_score(infos) 19 elif s == '5': 20 output_by_score_desc(infos) 21 elif s == '6': 22 output_by_score_asc(infos) 23 elif s == '7': 24 output_by_age_desc(infos) 25 elif s == '8': 26 output_by_age_asc(infos) 27 elif s == 'q': 28 break 29 30 main() 31