2021-10-8

本文介绍了Python中装饰器的三种实现方式,包括直接修改函数、使用高阶函数和定义装饰器,并通过实例展示了如何统计函数执行时间和在函数前后添加额外操作。此外,还详细讲解了模块的导入机制,包括import、from...import...的不同用法,以及重命名导入。最后,探讨了包的导入原理和如何使用math、random、time等标准库进行数值计算和时间处理。
摘要由CSDN通过智能技术生成

装饰器、模块(2021-10-8)

一、给函数添加功能

1、给函数新增功能方案一:直接修改原函数,把新增的功能加进去

存在的问题:如果多个函数都需要新增相同的功能,则需要写多个相同的代码

import time
def download(name):
    start = time.time()
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))
    print(f'{name}结束下载')
    end = time.time()
    print(f'总时长 = {end - start}s')
download('长津湖')
-----------------------------------------------------------------------------------
def func1():
     start = time.time()
     num1 = float(input('请输入数字1:'))
     num2 = float(input('请输入数字2:'))
     print(f'{num1} + {num2} = {num1 + num2}')
     end = time.time()
    print(f'总时间:{end - start}s')
func1()
2、给函数新增功能方案二:实参高阶函数

存在的问题:主次不分明,且别人不易调用(适合自己一个人看)

def download2(name='电影1'):
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))
    print(f'{name}下载结束')

def total_time(fn):
    start = time.time()
    fn()
    end = time.time()
    print(f'总时长 = {end - start}s')
total_time(download2)
3、给函数新增功能方案三:装饰器
def total_time(fn):
    def new_fn():
        start = time.time()
    	fn()
    	end = time.time()
    	print(f'总时长 = {end - start}s')
    return new_fn
@total_time
def download3(name='电影1'):
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))
    print(f'{name}下载结束')
download3('长津湖')

二、装饰器语法

装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法

1、固定结构
def 装饰器名称(旧函数):def 新函数(*args, **kwargs):

​				result = 旧函数(*args, **kwargs):

​				实现新增的功能

​				return result

​		return 新函数

练习1:写一个统计函数执行时间的装饰器

def total_time(fn):
    def new_fn(*args, **kwargs):
        start = time.time()
        result = fn(*args, **kwargs)
        end = time.time()
        print(f'总时间:{end - start}')
        return result
    return new_fn
@total_time
def download(name):
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))
    print(f'{name}结束下载')
download('长津湖')

练习2:写一个装饰器在原函数的开头打印 start

def begin_logo(fn):
    def new_fn(*args, **kwargs):
        print('start')
        result = fn(*args, **kwargs)
        return result
    return new_fn
@begin_logo
def download(name):
    print(f'{name}开始下载')
    time.sleep(randint(1, 3))
    print(f'{name}下载结束')
download('长津湖')

练习3:将返回值是数字的函数的返回值变成原来的10000倍

def blow_up(fn):
    def new_fn(*args, **kwargs):
        result = fn(*args, **kwargs)
        if type(result) == (int, float)
        	return result * 10000
        return result
    return new_fn

三、模块的导入

1、模块

一个py文件就是一个模块

可以在一个模块中使用另外一个模块中的内容

前提:1)被另一个模块使用的模块名必须符合变量名的要求

​ 2)被使用之前需要导入

2、导入模块(重)
1)import 模块名 - 直接导入指定模块,导入后能通过’模块名.‘的方式使用模块中所有的全局变量
import random
random.randint(10, 20)
2)from 模块名 import 变量名1,变量名2,变量名3,… - 通过模块导入指定变量,导入后直接使用指定的变量
from random import randint
randint(10, 20)
3)from 模块名 import * - 通过模块导入模块中所有全局变量,导入后直接使用变量
from random import *
randint(10, 20)
4)重命名
a、import 模块名 as 新模块名 - 使用模块的时候用新模块名来使用
import random as rd
rd.randint(10, 20)
b、from 模块名 import 变量名1 as 新变量名1, 变量名2, 变量名3,…
from random import randint as rdt
rdt(10, 20)

四、导入模块的原理

1、原理

当代码执行到导入模块的时候,系统会自动进入该模块中所有的代码都执行一遍

from download_file import download_film

print(f'04:{__name__}')
download_film('这个杀手不太冷')

这个if语句的特点:在if语句中的代码当前模块被别的模块导入的时候不会执行;如果直接运行当前模块又会执行

if __name__ == '__main_-':
    pass

五、包的导入

1、导入包中的模块(重要)
1)import 包名 - 要修改__init.py文件才有意义,否则无用
import fileManager
2)import 包名.模块名
a. 不重命名
import fileManager.csvFile
print(fileManager.csvFile.aa)
fileManager.csvFile.read_file()

b. 重命名
import fileManager.csvFile as csvFile
print(csvFile.aa)
csvFile.read_file()
3)from 包名.模块名 import 变量1, 变量2,…
from fileManager import csvFile, jsonFile
print(csvFile.aa)
jsonFile.write_dict()
4)from 包名.模块名 import 变量1, 变量2,…
from fileManager.csvFile import read_file
read_file()
2、导入包的原理

导入包中的模块的内容的时候,系统会先执行包中__init__.py文件中的内容,再执行模块中的内容

from fileManager import csvFile

功能一:

import fileManager
fileManager.csvFile.read_file()
fileManager.jsonFile.write_dict()

功能二:

from fileManager.jsonFile import write_dict

from fileManager import write_dict
write_dict()

import fileManager
fileManager.write_dict()
fileManager.open_file()

from fileManager import open_file, write_dict
open_file()

六、数学模块

math - 普通数字相关的数学函数

cmath - 复数相关的数学函数

普通数字(int、float):100、-23、0.34、…

复数(complex):a+bj (a-实部、b-虚部、j是虚数单位:j**2 == -1)

x = 10 + 2j
y = 20 - 3j
print(type(x))   # <class 'complex'>

print(x + y)     # 30 - 1j
print(x * y)     # 206 + 10j
1、ceil(浮点数) - 将浮点数转换成整数(向大取整)
print(math.ceil(1.9))    # 2
print(math.ceil(1.1))    # 2
2、floor(浮点数) - 将浮点数转换成整数(向小取整)
print(math.floor(1.9))    # 1
print(math.floor(1.1))    # 1
3. round(浮点数) - 将浮点数转换成整数(四舍五入)
print(round(1.9))       # 2
print(round(1.1))       # 1
import random

# randrange(M,N,step)   -  随机整数
print(random.randrange(10, 20, 2))

# randint(M, N)  - 随机整数
print(random.randint(10, 20))

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

七、时间模块

import time
import datetime
1、获取当前时间

时间戳:以当前时间到1970年1月1日0时0分0秒(格林威治时间)的时间差来记录一个时间(时间差的单位是秒)

t1 = time.time()
print(t1)              # 1633683338.1856189
2. 获取本地时间

localtime() - 获取当前的本地时间(返回值是结构体时间)

t2 = time.localtime()
print(t2, t2.tm_year)

# localtime(时间戳)  -  回去指定时间戳对应的本地时间
t3 = time.localtime(0)
print(t3)

t4 = time.localtime(1633683338.1856189)
print(t4)
3、睡眠 - 让程序暂停运行
sleep(时间)   -  时间单位:秒
time.sleep(2)
print('==================')
4.将结构体时间转换成时间戳
mktime(结构体时间)
t5 = time.mktime(t2)
print(t5)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值