day13-14-15 装饰器、模块、包、系统常用模块(数学、时间、随机、OS、hashlib机模块)
作业:挑出os中重要的
装饰器(decorator)
1. 给函数添加功能
装饰器的作用:给已经写好的函数新增功能
例1:给函数新增功能:统计程序运行的时间并打印
需求:增加功能,(打印电影下载的时长)在最后打印end
def download(name):
print(f'{name}开始下载')
time.sleep(randint(1, 3))
print(f'{name}下载结束')
download('花儿与少年')
import time
from random import randint
def download_new(name):
start = time.time()
print(f'{name}开始下载')
time.sleep(randint(1, 3))
print(f'{name}下载结束')
end = time.time()
print(f'总时间:{end - start}s')
download_new('花儿与少年')
def total_time(fn):
start = time.time()
fn()
end = time.time()
print(f'总时间:{end - start}s')
total_time(download())
def total_time(fn):
def new_fn():
start = time.time()
fn()
end = time.time()
print(f'总时间:{end - start}s')
return new_fn
def logo(fn):
def new_fn():
fn()
print('千锋教育')
return new_fn
@logo
def download3(name='电影1'):
print(f'{name}开始下载')
time.sleep(randint(1, 3))
print(f'{name}下载结束')
@total_time
def func12():
num1 = float(input('请输入数字1:'))
num2 = float(input('请输入数字2:'))
print(f'{num1} + {num2} = {num1 + num2}')
download3()
func12()
2. 装饰器语法
装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法
1. 固定结构
'''
def 装饰器名称(旧函数):
def 新函数():
# 给新函数添加原函数的参数(位置参数,关键字参数)
旧函数()
# 将上述参数传给原函数,并用变量接收原函数的返回值
实现新增的功能
# 新增功能不同,实现新增的功能的代码的位置可能不同
return 新函数
'''
@ add_logo
def func2():
return 100
print(func2)
改进后的装饰器:(重要 ! ! ! )
'''
def 装饰器名称(旧函数):
def 新函数(*args, **kwargs):
# 给新函数添加原函数的参数(位置参数,关键字参数)
result = 旧函数(*args, **kwargs)
# 将上述参数传给原函数,并用变量接收原函数的返回值
实现新增的功能
# 新增功能不同,实现新增的功能的代码的位置可能不同
return result
# 返回原函数的返回值,也可能返回的是与原函数返回值有关系的值
return 新函数
'''
def add_logo(fn):
def new_fn(*args, **kwargs):
result = fn(*args, **kwargs)
print('新功能!')
return result
return new_fn
@add_logo
def func():
print('hello world!')
@add_logo
def func1(x):
print(x * 2)
@add_logo
def func2():
return 100
func()
func1(100)
func1(x=200)
print(func2())
用@使用装饰器的原理:
@add_logo
练习:
import time
def total_time(fn):
def new_fn(*args, **kwargs):
start = time.time()
result = fn(*args, **kwargs)
end = time.time()
print(f'总用时:{end - start}s')
return result
return new_fn
@ total_time
def add_nums(num1,num2):
print(f'{num1} + {num2} =', num1 + num2)
add_nums(2,3)
def total_start(fn):
def new_fn(*args, **kwargs):
print('start')
result = fn(*args, **kwargs)
return result
return new_fn
def enlarge(fn):
def new_fn(*args, **kwargs):
result = fn(*args, **kwargs)
if type(result) in (int,float):
return result * 10000
return result
return new_fn
模块
1. 模块
一个py文件就是一个模块 可以在一个模块中使用另外一个模块中的内容,前提: 1)被另外一个模块使用的模块的名字必须符合变量名的要求 2)被使用之前需要导入
2. 导入模块(重要)
'''
1) import 模块名
- 直接导入指定模块,导入后能通过"模块名."的方式使用模块中所有的全局变量
2)from 模块名 import 变量名1,变量名2,变量名3,...
- 通过模块导入指定变量,导入后直接使用指定变量(只能使用导入的变量)
3)from 模块名 import *
- 通过模块导入所有全局变量,导入后直接使用变量
4) 重命名
import 模块名 as 新模块名
- 使用模块的时候用新模块名来使用
from 模块名 import 变量名1 as 新变量名1,
重名名导入方法的一般使用场景:
a.不喜欢导入的模块中的变量名
b.导入的模块中的变量名与现有程序中的变量名或类重名
'''
a = 100
for x in range(3):
pass
def func1():
print('test1中的函数')
import test1
print(test1.a)
print(test1.x)
test1.func1()
from test1 import a, x
print(a)
print(x)
from test1 import *
print(a)
print(x)
func1()
test1.func1()
import test1 as ts1
test1 = '花儿'
print(test1, ts1.a)
ts1.func1()
from test1 import x as t_x
x = '小明'
print(x, t_x)
3. 导入模块的原理
当代码执行到导入模块的时候,系统会自动进入该模块将模块中的代码都执行一遍(不管导入的时候导入的全部模块还是模块中部分变量都会全部执行一遍)
import test1
from test1 import a
想要在导入模块时只执行被导入模块内的部分代码:
在被导入的模块内输入以下内容(只需输入main即可出现相应代码提示):
a = 100
for x in range(3):
pass
def func1():
print('test1中的函数')
if __name__ == '__main__':
func1()
print(x + 2)
上述if语句的特点:
-
当该模块被别的模块导入时,别的模块中不会if语句内部的代码,只会执行if语句外部的代码; -
但是,不管放在if语句内部还是外部,都不会影响当前模块的执行
if语句内代码不被执行的原因:
每个py文件运行时,当前py文件的 __ name __ 的值会变成’ __ main __ ‘,其他文件的 __ name __ 的值会变成’ __ py文件的文件名 __ ’
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w5viIJ7B-1633692482071)(C:\Users\32873\AppData\Roaming\Typora\typora-user-images\image-20211008143705419.png)]
包
包:一个文件夹就是一个包
包主要用于:一个工程文件中有很多py文件,可通过文件夹的方式对py文件进行分类
创建包: 1)直接创建包: 工程文件下 → new → Python_Package → 包的名称 2)通过创建文件夹的方式创建包: 工程文件下 → new → Directory → 文件夹的名称 → 再在该文件夹下创建名称为"__ init __"的py文件,此时该文件夹会自动变成包文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NjsgqhRf-1633692482072)(C:\Users\32873\AppData\Roaming\Typora\typora-user-images\image-20211008144846738.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y2RWENOH-1633692482073)(C:\Users\32873\AppData\Roaming\Typora\typora-user-images\image-20211008145339926.png)]
1. 导入包中的模块(重要)
导入包的写法:
'''
1) import 包名 - 要修改__init__.py文件才有意义,否则无用
2)import 包名.模块名
3)from 包名 import 模块名
4)from 包名.模块名 import 变量名1,变量名2,变量名3,...
'''
aa = 100
def read_file():
print('获取csv文件')
bb = 200
def write_dict():
print('将字典谢写入json文件')
cc = 300
import file_manager
print(file_manager.csvFile.aa)
import file_manager.csvFile
print(file_manager.csvFile.aa)
file_manager.csvFile.read_file()
import file_manager.csvFile as csvFile
print(csvFile.aa)
csvFile.read_file()
from file_manager import csvFile, jsonFlie
print(csvFile.aa)
jsonFlie.write_dict()
from file_manager.csvFile import read_file
read_file()
2. 导入包的原理
导入包中的模块的内容,系统会先执行包中__ init __ .py文件中的内容,再执行模块中的内容:
- 如果只是关联了包就只执行__ init __ .py文件
- 如果还关联了包中的其他模块,就先执行__ init __ .py文件,再执行包中其他模块的内容
3. 包中__ init __.py文件的用法
可以什么都不写
常用功能:
-
功能一:导入包中所有模块,让在外部直接导入包的时候就可以通过包去使用包中所有的模块 from file_manager import csvFile, jsonFlie, testFile
-
功能二:建立常用方法和数据的快捷键
from file_manager.jsonFlie import write_dict
-
功能三:封装通用函数 __ init __中的函数,直接导入包就可以使用 def open_file():
print('打开文件')
系统常用模块的使用
1. 数学模块math, cmath
math,cmath内容几乎一样 math - 普通数字相关的数学函数 cmath - 复数相关的数据函数
普通数字(int、float):100、-12.5、0.23 复数(complex):a+bj (a-实部、b-虚部、j-虚部范围,j2=-1)
x = 10 + 2j
y = 20 - 1j
print(type(x))
print(x + y)
print(x * y)
1.1 ceil(浮点数)
ceil(浮点数) - 将浮点数转换为整数(向大取整),math模块中的函数,采用math.ceil(浮点数)的写法使用
print(math.ceil(1.9))
print(math.ceil(1.1))
1.2 floor(浮点数)
floor(浮点数) - 将浮点数转换为整数(向小取整)
print(math.floor(1.9))
print(math.floor(1.1))
1.3 round(浮点数)
round(浮点数) - 将浮点数转换为整数(四舍五入)
print(round(1.9))
print(round(1.1))
2. 随机数模块random
注意:random为系统函数,可直接使用
import random
2.1 randrange(M, N, step) - 随机整数
print(random.randrange(10, 20, 2))
2.2 randint(M, N, step) - 随机整数
print(random.randint(10, 20))
2.3 random() - 产生0~1的随机小数,不用传参
print(random.random())
print(random.random() * 10)
print(random.random() * 9 + 1)
3. 随机抽取(属于random)
3.1 choices(序列) - 从序列中随机获取一个元素
nums = [1, 2, 3, 4, 5]
print(random.choice(nums))
3.2 choices(序列,k=数量) - 从序列中随机获取指定数量的元素(有放回)
print(random.choices(nums, k=3))
3.3 sample(序列,k=数量) - 从序列中随机获取指定数量的元素(无放回)
print(random.sample(nums, k=4))
3.4 shuffle(序列) - 将原有序列随机打乱,直接将原有序列打乱,无返回值
random.shuffle(nums)
print(nums)
4. 时间模块time\datetime (时间管理—非常重要)
import time
4.1 获取当前时间 time()
time() - 获取当前时间
时间戳:以当前时间距离到1970年1月1日0时0分0秒(格林威治时间(格林威治时间和北京时间有8小时时差,系统会自动处理这个时差))的时间差来记录一个时间(时间差的单位是秒)
t1 = time.time()
print(t1)
4.2 获取本地时间 localtime()
localtime() - 获取当前的本地时间
t2 = time.localtime()
print(t2)
localtime(时间戳) - 返回指定时间戳对应的本地时间
t3 = time.localtime(0)
print(t3)
print(t3.tm_year)
t4 = time.localtime(1633683364.2705839)
print(t4)
4.3 睡眠 - 让程序暂停运行
sleep(时间) - 时间单位:秒
print('=========')
time.sleep(2)
print('+++++++++++')
4.4 将结构体时间转换成时间戳
mktime(结构体时间)
t5 = time.mktime(t4)
print(t5)
4. OS (文件和文件夹的管理—重要)
5. hashlib (了解)
=1, tm_isdst=0)
tm_hour=8。格林威治1970年1月1日0时0分0秒对应本地时间为北京时间当日的8点
print(t3.tm_year) # 1970,获取年
t4 = time.localtime(1633683364.2705839) print(t4)
time.struct_time(tm_year=2021, tm_mon=10, tm_mday=8, tm_hour=16, tm_min=56, tm_sec=4, tm_wday=4, tm_yday=281, tm_isdst=0)
## 4.3 睡眠 - 让程序暂停运行
sleep(时间) - 时间单位:秒
```python
# sleep(时间) - 时间单位:秒
print('=========')
time.sleep(2)
print('+++++++++++')
4.4 将结构体时间转换成时间戳
mktime(结构体时间)
t5 = time.mktime(t4)
print(t5)
4. OS (文件和文件夹的管理—重要)
5. hashlib (了解)
|