day11-三大神器

高阶函数

1.函数作为变量

python 中声明函数就是声明一个类型为function的变量,函数名就是变量名
普通变量能做的事情函数都可以做

def fun1():
    print('函数1')
    return 100


print(type(fun1))

2.普通变量能做的事情函数都可以做

1)一个变量可以给另一个变量赋值

a = 100
b = a
print(b, b + 10)


def fun2():
    print('函数2')
    return 200


b2 = fun2
print(type(b2), b2())
# 2)修改变量的值

fun3 = 100
# fun3()      TypeError: 'int' object is not callable

# 3)变量作为序列元素
a = 10
list1 = [a, 100, 'abc']
print(list1)

list2 = [fun2, fun2(), 10]
print(list2[0]())


# 4)变量作为函数的参数
def func3(x):
    print('函数5:', x)


a = 100
func3(a)
func3(fun2)

3.将函数作为函数的参数 - 实参高阶函数

def fun4(x):
    y = x()
    return y


re = fun4(fun2)
print(re)

2.系统的实参高阶函数
列表.sort()、sorted()、max()、min()都是实参高阶函数,因为这四个函数中都有一个参数key,要求是一个函数

nums = [10, 89, 78, 7]
nums.sort(reverse=True)
print(nums)

1)排序方法:参数key要求是一个函数,作用是用来定制排序规则(默认按元素的大小从小到大或从大到小)
参数key的要求
a.key是一个函数
b.函数中有且只有一个参数,这个参数指向的是序列中的每个元素
c.函数需要一个返回值,这个返回值就是排序的时候比较大小的对象


# def func_key(item):
#     return item % 10


# nums.sort(key=func_key)
nums.sort(key=lambda x: x % 10)
print(nums)

students = [
    {'name': '小明', 'age': 18, 'score': 90},
    {'name': '小花', 'age': 23, 'score': 78},
    {'name': '小兰', 'age': 17, 'score': 65},
    {'name': '小红', 'age': 30, 'score': 89}
]

students.sort(reverse=True, key=lambda item: item['score'])
print(students)

students.sort(key=lambda item: item['score'] + item['age'])
print(students)

# 2)max、min直接比较元素的大小求出最大最小值
nums = [100, 39, 51, 62, 58]
max1 = max(nums)
print(max1)

max2 = max(nums, key=lambda i: i % 10)
print(max2)

3)max函数的原理

def max1(seq, key=None):
    t_seq = list(seq)
    t_max = t_seq[0]

    if not key:
        for item in t_seq[1:]:
            if item > t_max:
                t_max = item
    else:
        for item in t_seq[1:]:
            if key(item) > key(t_max):
                t_max = item
    return t_max


print(max((10, 9, 8, 67), key=lambda item: item % 10))
print(max1((10, 9, 8, 67), key=lambda item: item % 10))

返回值高阶函数

1.变量可以作为函数的返回值

def sum1(x, y):
    t = x + y
    return t


print(sum1(10, 20))


# 函数作为函数的返回值 - 返回值高阶函数
# func1就是一个返回值高阶函数
def func1():
    def func2():
        print('函数2')

    return func2


print(func1())
func1()()
print(func1()())

2.闭包 - 函数1中声明了一个函数2,并且在函数2中使用了函数1的数据,那么这个函数1就是一个闭包

闭包的特点:闭包函数中的数据不会因为函数调用结束而销毁

def func3():
    a = 10

    def func4():
        print(a)

    return func4


t = func3()
t()


# 面试题1:
list1 = []
for i in range(5):
    list1.append(lambda x: x*i)  # 声明函数不会执行函数体,所以list1中五个函数都是一样的
# i = 4
print(list1[1](2), list1[2](2), list1[3](2))


# 面试题2
def func2(seq=[]):
    seq.append(10)
    return seq


print(func2())
print(func2())

# 练习:写出打印列表

list3 = [1, 2]


def func3(seq=list3):
    seq.append(10)
    return seq


func3()
list3.append(100)
print(func3())

装饰器

1.什么是装饰器

装饰器本质是一个函数 = 返回值高阶函数 + 实参高阶函数 + 糖语法
装饰器是python的三大神器之一:装饰器,迭代器,生成器
作用:给已经写好的函数添加功能

# 给函数添加一个功能:统计函数的执行时间


# 方法一:在每个需要添加功能的函数中加入相应的代码
def sum_w(x, y):
    start = time.time()  # 获取当前时间
    sum1 = x+y
    print(sum1)
    end = time.time()
    print('函数执行时间:%fs' % (end - start))


sum_w(100, 200)


def factorial(n):
    start = time.time()

    num1 = 1
    for num in range(1, n+1):
        num1 *= num
    print('%d的阶乘是:%d' % (n, num1))
    end = time.time()
    print('执行时间是:%fs' % (end-start))


factorial(5)


# 方法二:

# 注意:这个add_time只能给没有参数的函数添加统计时间的功能
def add_time(fn):
    # fn = func1
    start = time.time()
    fn()
    end = time.time()
    print('函数执行的时间:%fs' % (end - start))


def add_time2(fn, *args, **kwargs):
    start = time.time()
    fn(*args, **kwargs)

    end = time.time()
    print('函数执行的时间:%fs' % (end - start))


def func1():
    print('===========')
    print('-----------')


def func2():
    print('你好世界')
    print('你好python')


def func3(x, y):
    print('%d+%d=%d' % (x, y, x+y))


add_time(func1)
add_time(func2)
add_time2(func1)

# func3(10, 20)
add_time2(func3, 10, 20)

2.装饰器

无参装饰器
def 函数名1(参数1):
def 函数名2(*args, **kwargs):
参数1()
新功能对应的代码段
return 函数名2

说明:
函数名1 - 装饰器的名字 - 一般根据需要添加的功能命名
参数1 - 需要添加功能的函数,一般命名fn
函数名2 - 随便命名, 可以用test

def add_time3(fn):
    def test(*args, **kwargs):
        start = time.time()
        fn(*args, **kwargs)
        end = time.time()
        print('函数执行的时间:%fs' % (end - start))

    return test


@add_time3
def func5():
    print('你好吗')


func5()


# 练习:给所有返回值是整数的函数添加功能;返回值以16进制形式的数据返回

def hex_1(fn):
    def test(*args, **kwargs):
        a = fn(*args, **kwargs)
        if isinstance(a, int):
            return hex(a)
        return a

    return test


@hex_1
def t_sum(x, y):
    return x+y


print(t_sum(10, 20))

解包操作

# 1.解包:在容器型数据类型前加*或者**可以对容器进行解包
# 注意: **只能放在字典的前面
list1 = [10, 20, 30]
print(*list1)  # -> 10 20 30


def func1(x, y, z):
    print(x, y, z)


func1(*list1)


# 练习:写一个函数,可以对多个数据进行不同的运算
def sum_1(*nums):
    num1 = 0
    for x in nums:
        num1 += x
    return num1


def sub_1(*nums):
    num1 = nums[0]
    for x in nums[1:]:
        num1 -= x
    return num1


def operation(char, *nums):
    if char == '+':
        return sum_1(*nums)

    elif char == '-':
        return sub_1(*nums)


print(operation('-', 9, 90, 80, 7, 60))

# 2)**是将字典解包
dict1 = {'x': 100, 'y': 200}  # **dict1 == x==100,y==200;*dict=x,y
print(*dict1)
"""
装饰器 - 用一个函数去装饰另外一个函数或类为其提供额外的功能
"""
import random
import time

from functools import wraps


def record_time(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f'{func.__name__}执行时间: {end - start}秒')
        return result

    return wrapper


@record_time
def download(filename):
    """下载"""
    print(f'开始下载{filename}')
    time.sleep(random.random() * 6)
    print(f'{filename}下载完成')


@record_time
def upload(filename):
    """上传"""
    print(f'开始上传{filename}')
    time.sleep(random.random() * 8)
    print(f'{filename}上传完成')


# download = record_time(download)
print(download.__name__, upload.__name__)
download('Python从入门到住院.pdf')
# 取消掉装饰器
download = download.__wrapped__
download('北京有点冷.avi')
upload('数据库从删库到跑路.pdf')

迭代器

1.什么是迭代器(iter)

迭代器也是python提供的容器型数据类型
迭代器存储数据的特点:一个迭代器可以存储多个数据,如果要获取元素必须将元素从迭代器中取出,
取一个少一个,取出来的数据不能再添加到迭代器中

2.将数据存入迭代器:1)将别的序列转换成迭代器 2)创建生成器

list1 = [10, 20, 30, 40]
iter1 = iter(list1)
print(iter1)

iter2 = iter('hello')
print(iter2)

3.获取迭代器中的元素

迭代器中的元素不管通过什么方式取出来了,那么这个元素在迭代器中就不存在了
1)获取单个元素
next(迭代器) -> 取出迭代器中最前面的元素

print(next(iter1))
print(next(iter1))
print(next(iter1))
print(next(iter1))


# 2)遍历 - 一个一个的取所有元素
for x in iter2:
    print('x', x)

print('================================')
iter3 = iter('python')
next(iter3)
next(iter3)
for i in iter3:
    print(i)


iter4 = iter('python')
list2 = list(iter4)
print(list2)
# print(next(iter4))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容