Cris 的Python笔记(七):函数进阶

版权声明:转载请注明出处~ 摸摸博主狗头 https://blog.csdn.net/cris_zz/article/details/83480205

函数式编程

'''
函数式编程
在Python 中,函数也是一等对象(Java 8 中函数才成为一等对象)
一等对象的特点:
1. 对象是在运行时期创建的
2. 可以赋值给变量作为数据结构中的元素
3. 可以作为参数传递
4. 可以作为返回值

函数式编程中的高阶函数至少要满足以下条件之一:
1. 接收一个或者多个函数作为参数
2. 返回值为函数类型
'''
# 练习
old_list = [1, 34, 2, 45, 23, 43, 26]

# 定义一个函数,判断数字是否是偶数


def judge_num1(num: int)->bool:
    return num % 2 == 0

# 定义一个函数,判断数字是否大于10


def judge_num2(num: int)->bool:
    return num > 10


def super_func(old_list: list, func)->list:
    new_list = []
    for i in old_list:
        if func(i):
            new_list.append(i)
    return new_list


# print(super_func(old_list, judge_num1))  # [34, 2, 26]
# print(super_func(old_list, judge_num2))  # [34, 45, 23, 43, 26]

匿名函数(lambda 表达式)以及内置函数filter,map,sorted和sort 方法

# filter()
# filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
#  1.函数,根据该函数来过滤可迭代对象
#  2.需要过滤的可迭代对象
# 返回值:
#   过滤后的可迭代对象(通过list()方法转换为列表数据类型)
print(list(filter(judge_num1, old_list)))   # [34, 2, 26]


# 匿名函数 lambda 函数表达式 (语法糖)
#   lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式
#   语法:lambda 参数列表 : 返回值(这里可以通过调用其他函数,或者直接写简单的处理代码)
#   匿名函数一般都是作为参数使用,其他地方一般不会使用
print(list(filter(lambda num: num > 10, old_list)))  # [34, 45, 23, 43, 26]
print(list(filter(lambda num: judge_num1(num), old_list)))  # [34, 2, 26]

# map()函数:映射,对可迭代对象中每个元素做指定操作,并返回新的元素组成的迭代对象
# [101, 134, 102, 145, 123, 143, 126]
print(list(map(lambda num: num + 100, old_list)))

# sort()
# 该方法用来对列表中的元素进行排序,直接操作原列表,没有返回值
# sort()方法默认是直接比较列表中的元素的大小
# 在sort()可以接收一个关键字参数 , key
#   key需要一个函数作为参数,当设置了函数作为参数
#   每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小
old_list.sort()
print(old_list)  # [1, 2, 23, 26, 34, 43, 45]

old_list = ['cris', '1234', 'a', 'james']
old_list.sort(key=len)
print(old_list)  # ['a', 'cris', '1234', 'james']

old_list = [1, '11', 23, 2, '0']
old_list.sort(key=int)
print(old_list)  # ['0', 1, 2, '11', 23],改变原列表的排序,不会改变元素的数据类型

# sorted()
# 这个函数和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序
#   并且使用sorted()排序不会影响原来的对象,而是返回一个新对象
names = (1, 4, 12, 0)
a = sorted(names)
print(a)    # [0, 1, 4, 12] 返回新列表
print(names)    # (1, 4, 12, 0) 原序列不变

闭包

# 将函数作为返回值返回,也是一种高阶函数
# 这种高阶函数我们也称为叫做闭包,通过闭包可以创建一些只有当前函数能访问的变量
#   可以将一些私有的数据藏到的闭包中,防止我们定义的变量被修改或者覆盖

# 如果我们想要定义一个函数用于计算平均值,用于不断的往列表中添加元素并计算,以下方式是很危险的
nums = []


def func(a: float)->float:
    nums.append(a)
    return sum(nums) / len(nums)


print(func(10))  # 10.0
print(func(30))  # 20.0
# nums = [100]
print(func(50))  # 30.0

# 形成闭包的要件
#   ① 函数嵌套(外部函数里面必须有内部函数)
#   ② 将内部函数作为返回值返回
#   ③ 内部函数必须要使用到外部函数的变量

# 以下闭包可以保护数据(nums)的安全,因为作用域的存在,对外部函数以外的范围不可见


def clouser_func():
    nums = []

    def func(num: int):
        nums.append(num)
        return sum(nums) / len(nums)
    return func


close_func = clouser_func()
print(close_func(22))   # 22.0
print(close_func(26))   # 24.0

装饰器

# 装饰器,类似Java 的动态代理,但是使用更加方便,可以对原有的函数进行扩展

# 示例如下:


def add(a: float, b: float)->float:
    return a + b


def sub(a: float, b: float, c: float)->float:
    return a - b - c


def decoration_func(fn):
    def new_func(*args, **kwargs):
        print('函数开始执行')
        result = fn(*args, **kwargs)
        print('函数执行完毕')
        return result
    return new_func


new_func = decoration_func(add)
print(new_func(1, 5))    # 6

print(decoration_func(sub)(1, 2, 3))  # -4

# Python 中的装饰器用法,使用 @装饰器函数 的方式为想要扩展的函数提供最简单的写法,此时再去调用原函数已经是装饰过后的函数了
#   可以同时为一个函数指定多个装饰器,这样函数将会按照从内向外的顺序被装饰


@decoration_func
def hello():
    print('hello,Cris')


hello()

猜你喜欢

转载自blog.csdn.net/cris_zz/article/details/83480205