IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> day14-15 装饰器、模块、包、系统常用模块(数学、时间、随机、OS、hashlib模块) -> 正文阅读

[Python知识库]day14-15 装饰器、模块、包、系统常用模块(数学、时间、随机、OS、hashlib模块)

day13-14-15 装饰器、模块、包、系统常用模块(数学、时间、随机、OS、hashlib机模块)

作业:挑出os中重要的

装饰器(decorator)

1. 给函数添加功能

装饰器的作用:给已经写好的函数新增功能

例1:给函数新增功能:统计程序运行的时间并打印

需求:增加功能,(打印电影下载的时长)在最后打印end

# 方案一:直接修改原函数,把新增的功能加进去
# 原函数:
def download(name):
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))  # 时间停顿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))  # 时间停顿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())
# 方案二的缺点:
# 只能给没有参数的函数添加统计时长的功能;
# 使用时,用户下载时想到的是download而不是total_time(直观性很差)

# 方案三:装饰器
# 装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法
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 新函数
'''
# 1)只能装饰没有参数(或者可以不用传参)的原函数
# 2)装饰完原函数的返回值消失
@ add_logo  # func2 = add_logo(func2)
def func2():
    return 100

print(func2)  # None,未得到原函数的返回值

改进后的装饰器:(重要 ! ! ! )

'''
def 装饰器名称(旧函数):
    def 新函数(*args, **kwargs):        
    # 给新函数添加原函数的参数(位置参数,关键字参数)
        result = 旧函数(*args, **kwargs)        
        # 将上述参数传给原函数,并用变量接收原函数的返回值
        实现新增的功能        
        # 新增功能不同,实现新增的功能的代码的位置可能不同
        return result        
        # 返回原函数的返回值,也可能返回的是与原函数返回值有关系的值
    return 新函数
'''

# 上述能够装饰所有函数,并得到相应返回值
# 例子:给函数添加并打印logo
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     # func2 = add_logo(func2)
def func2():
    return 100

func()

func1(100)
func1(x=200)

print(func2())

用@使用装饰器的原理:

@add_logo     # 等同于:func2 = add_logo(func2)

练习:

# 练习1:写一个统计函数执行时间的装饰器
import time
def total_time(fn):
    def new_fn(*args, **kwargs):
        start = time.time()
        result = fn(*args, **kwargs)
        # time.sleep(1)
        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)
# 练习2:写一个装饰器在原函数的开头打印 start
def total_start(fn):
    def new_fn(*args, **kwargs):
        print('start')
        result = fn(*args, **kwargs)
        return result
    return new_fn
# 练习3:将返回值是数字的函数的返回值变成原来的10000倍
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.导入的模块中的变量名与现有程序中的变量名或类重名

'''
# test1.py
a = 100

for x in range(3):
    pass

def func1():
    print('test1中的函数')
# ======导入方式1===========
import test1

print(test1.a)  # 100
print(test1.x)  # 2
test1.func1()  # test1中的函数

# ======导入方式2===========
from test1 import a, x

print(a)  # 100
print(x)  # 2
# func1()  # 报错。未导入test1中的func1,故不能使用
# test1.func1()  # 报错。未导入test1中的func1,故不能使用

# ======导入方式3===========
from test1 import *

print(a)  # 100
print(x)  # 2
func1()  # test1中的函数
test1.func1()  # test1中的函数

# ======导入方式4.1===========
import test1 as ts1
test1 = '花儿'
print(test1, ts1.a)  # 花儿 100
ts1.func1()  # test1中的函数

# ======导入方式4.2===========
from test1 import x as t_x
x = '小明'
print(x, t_x)   # 小明 100

3. 导入模块的原理

当代码执行到导入模块的时候,系统会自动进入该模块将模块中的代码都执行一遍(不管导入的时候导入的全部模块还是模块中部分变量都会全部执行一遍)

import test1  # 会将test1.py中的所有代码执行一遍
from test1 import a  # 会将test1.py中的所有代码执行一遍

想要在导入模块时只执行被导入模块内的部分代码:

在被导入的模块内输入以下内容(只需输入main即可出现相应代码提示):

# 想要在导入模块时执行的代码,例如:
a = 100

for x in range(3):
    pass

def func1():
    print('test1中的函数')
    
#=================== 
# (重要写法!!!!!!!!)  
#===================
if __name__ == '__main__': 
	# 不想在导入模块时执行的代码: 例如:
	func1()
    print(x + 2)

上述if语句的特点:

  1. 当该模块被别的模块导入时,别的模块中不会if语句内部的代码,只会执行if语句外部的代码;

  2. 但是,不管放在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,...
'''
# 建立一个包,名称为file_manager,该包内有以下py文件:

# csvFile.py
aa = 100

def read_file():
    print('获取csv文件')


# jsonFile.py
bb = 200

def write_dict():
    print('将字典谢写入json文件')
    
    
# testFile.py
cc = 300
# 导入包以及包中模块的方法:

# =========导入方式1=============
import file_manager  # 该行代码只执行包中的__init__.py文件

print(file_manager.csvFile.aa)


# =========导入方式2=============
# a.不重命名
import file_manager.csvFile # 该行代码只执行包中的__init__.py文件和csvFile.py文件

print(file_manager.csvFile.aa)
file_manager.csvFile.read_file()

# b.重命名
import file_manager.csvFile as csvFile

print(csvFile.aa)
csvFile.read_file()


# =========导入方式3=============
from file_manager import csvFile, jsonFlie

print(csvFile.aa)
jsonFlie.write_dict()


# =========导入方式4=============
from file_manager.csvFile import read_file

read_file()

2. 导入包的原理

导入包中的模块的内容,系统会先执行包中__ init __ .py文件中的内容,再执行模块中的内容:

  • 如果只是关联了包就只执行__ init __ .py文件
  • 如果还关联了包中的其他模块,就先执行__ init __ .py文件,再执行包中其他模块的内容

3. 包中__ init __.py文件的用法

可以什么都不写

常用功能:

  1. 功能一:导入包中所有模块,让在外部直接导入包的时候就可以通过包去使用包中所有的模块

    from file_manager import csvFile, jsonFlie, testFile
    
  2. 功能二:建立常用方法和数据的快捷键

    # write_dict = jsonFile.write_dict
    from file_manager.jsonFlie import write_dict
    
  3. 功能三:封装通用函数

    __ 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  # 1必须写,否则会报错

print(type(x))  # <class 'complex'>

print(x + y)  # (30+1j)。实部和实部相加,虚部与虚部相加
print(x * y)  # (202+30j)。实部和虚部交叉相乘后再相加

1.1 ceil(浮点数)

ceil(浮点数) - 将浮点数转换为整数(向大取整),math模块中的函数,采用math.ceil(浮点数)的写法使用

print(math.ceil(1.9))  # 2
print(math.ceil(1.1))  # 2

1.2 floor(浮点数)

floor(浮点数) - 将浮点数转换为整数(向小取整)

print(math.floor(1.9))  # 1
print(math.floor(1.1))  # 1

1.3 round(浮点数)

round(浮点数) - 将浮点数转换为整数(四舍五入)

print(round(1.9))  # 2
print(round(1.1))  # 1

2. 随机数模块random

注意:random为系统函数,可直接使用

import random

2.1 randrange(M, N, step) - 随机整数

# randrange(M, N, step)     -   随机整数
print(random.randrange(10, 20, 2))  # [10,20)范围内的随机偶数

2.2 randint(M, N, step) - 随机整数

# randint(M, N, step)     -   随机整数
print(random.randint(10, 20))  # [10,20)范围内的随机整数

2.3 random() - 产生0~1的随机小数,不用传参

# random()    -   产生0~1的随机小数,不用传参
print(random.random())  # 0~1
print(random.random() * 10)  # 0~10
print(random.random() * 9 + 1)  # 1~10

3. 随机抽取(属于random)

3.1 choices(序列) - 从序列中随机获取一个元素

# choices(序列)  - 从序列中随机获取一个元素
nums = [1, 2, 3, 4, 5]
print(random.choice(nums))  # 4

3.2 choices(序列,k=数量) - 从序列中随机获取指定数量的元素(有放回)

# choices(序列,k=数量)  - 从序列中随机获取指定数量的元素(有放回)
print(random.choices(nums, k=3))  # [1, 5, 5]

3.3 sample(序列,k=数量) - 从序列中随机获取指定数量的元素(无放回)

# sample(序列,k=数量)  - 从序列中随机获取指定数量的元素(无放回)
print(random.sample(nums, k=4))  # [2, 3, 1, 5]

3.4 shuffle(序列) - 将原有序列随机打乱,直接将原有序列打乱,无返回值

# shuffle(序列)   -  将原有序列随机打乱,直接将原有序列打乱,无返回值
random.shuffle(nums)
print(nums)  # [4, 2, 5, 3, 1]

4. 时间模块time\datetime (时间管理—非常重要)

import time

4.1 获取当前时间 time()

time() - 获取当前时间

时间戳:以当前时间距离到1970年1月1日0时0分0秒(格林威治时间(格林威治时间和北京时间有8小时时差,系统会自动处理这个时差))的时间差来记录一个时间(时间差的单位是秒)

t1 = time.time()
print(t1)  # 1633683364.2705839,时间戳

# 时间戳:以当前时间距离到1970年1月1日0时0分0秒(格林威治时间(格林威治时间和北京时间有8小时时差,系统会自动处理这个时差))的时间差来记录一个时间(时间差的单位是秒)

# '2021年10月8日 16:56:00'  # 这是生活中的时间表达方式,实际开发中中一般不这样存储时间,内存消耗特别大(共15个字节),都是采用时间戳存储时间

4.2 获取本地时间 localtime()

localtime() - 获取当前的本地时间

# localtime()   -   获取当前的本地时间
t2 = time.localtime()
print(t2)
# time.struct_time(tm_year=2021, tm_mon=10, tm_mday=8,
# tm_hour=17, tm_min=10, tm_sec=57, tm_wday=4, tm_yday=281, tm_isdst=0)
# tm_wday 一周中的第几天
# tm_yday 当年的第几天
# tm_isdst是否是夏令时

localtime(时间戳) - 返回指定时间戳对应的本地时间

# localtime(时间戳)   -   返回指定时间戳对应的本地时间
t3 = time.localtime(0)
print(t3)
# time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=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(时间) - 时间单位:秒

# sleep(时间) -   时间单位:秒
print('=========')
time.sleep(2)
print('+++++++++++')

4.4 将结构体时间转换成时间戳

mktime(结构体时间)

# mktime(结构体时间)
t5 = time.mktime(t4)
print(t5)  # 1633683364.0

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(结构体时间)

# mktime(结构体时间)
t5 = time.mktime(t4)
print(t5)  # 1633683364.0

4. OS (文件和文件夹的管理—重要)

5. hashlib (了解)

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:14:15  更:2021-10-09 16:16:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:37:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码