Python语言基础6:递归、高阶函数、装饰器

Python语言基础6:递归、高阶函数、闭包、装饰器 学习笔记

递归

简单理解就是自己引用自己


# 创建一个变量保存结果
n = 10
for i in range(1,10): #range(n,m)函数包含n,不包含m
    n *= i
print(n)

# 创建一个函数,求任意数的阶乘
def fn_recursion(n):
    '''
    该函数用来求任意数的阶乘
    参数:
        n 表示所要求阶乘的数
    '''
    # 创建一个变量,来保存结果
    result = n
    for i in range(1,n):
        result *= i
    return result

print(fn_recursion(10))

# 递归式的函数:在函数中自己调用自己
# 无穷递归:如果这个函数被调用,程序的内存就会溢出,效果类似死循环
'''
def fn():
    fn()
fn()
'''

'''
递归是解决问题的一种方式,它和循环很像
    它的整体思想是:将一个大问题分解为一个个小问题,
    直到无法分解时,再去解决问题
递归式函数的两个条件
    1 基线条件:问题可以被分解为最小问题,当满足基线条件时,递归就不再执行
    2 递归条件:将问题继续分解的条件

递归和循环类似,基本是可以互相代替的
递归要求能看懂即可
10! = 10 * 9!
9! = 9 * 8!
...
2! = 2 * 1!
1! = 1

'''
def factorial(n):
    '''
    该函数用来求任意数的阶乘
    参数:n 表示要求阶乘的数
    '''
    # 基线条件:判断n 是否为1 ,如果为1 ,则测试不能继续分解
    if n == 1:
        # 1 的阶乘就是1 ,因此直接返回1
         return 1
    # 递归条件
    return n * factorial(n-1)
print(factorial(10))

# 创建一个函数power 来为任意数字做幂运算 n ** i
def power(n,i):
    '''
    :param n: 要做幂运算的数字
    :param i: 做幂运算的次数
    '''
    # 基线条件
    if i == 1:
        # 求 1 次幂
        return n
    # 递归条件
    return n * power(n , i-1)

print(power(5,3))

# 创建一个函数,用来检查一个任意的字符串是否是回文字符串,如果是则返回True,否则返回False
# 回文字符串:正反念都是一样的,eg:abcba
# 先检查第一个字符和最后一个字符是否一致,
# 如果不一致,则不是回文字符串,如果一致,则检查剩下部分
# 检查 abcdedcba 是不是回文
# 检查  bcdedcb  是不是回文
# 检查   cdedc   是不是回文
# 检查   ded     是不是回文
# 检查    e      是不是回文
def hui_wen(s):
    '''
    该函数用来检查指定的字符串是否是回文字符串,是则返回True,否则返回False
    :param s: 要检查的字符串
    :return:
    '''
    # 基线条件
    if len(s) < 2 :
        # 字符串长度小于2 ,则字符串一定是回文
        return True
    elif s[0] != s[-1]:
        # 第一个字符和最后一个字符不相等,不是回文字符串
        return False
    # 递归条件
    return hui_wen(s[1:-1])

print(hui_wen('abcdcba'))

高阶函数 :

接收函数作为参数,或者将函数作为返回值的函数四高阶函数
当我们使用一个函数作为参数时,实际上是将指定的代码传递进了目标函数


# 创建一个列表
from numpy import sort

l = [1,2,3,4,5,6,7,8,9]


# 定义一个函数,检查一个任意数字是否是偶数
def fn2(i):
    if i % 2 == 0:
        return True
    return False


# 定义一个函数,检查指定的数字是否大于5
def fn3(i):
    if i > 5:
        return True
    return False
# 定义有一个函数
# 可以指定列表中的所有偶数,保存到一个新的列表中返回
def fn(fnc,lst):
    '''
    fn() 函数可以将指定列表中的所有偶数获取出来,保存到一个新列表中返回
    :param lst: 要进行筛选的列表
    :return:
    '''

    # 创建一个新列表
    new_list = []

    # 对列表进行筛选
    for n in lst:
        # 判断n 的奇偶
        if fn3(n):
            new_list.append(n)
    # 返回新列表
    return new_list
def fn4(i):
    if i % 3 == 0:
        return True
    return False

# print(fn(fn2,l))

# filter() 可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
# 1 函数,根据该函数来过滤序列(可迭代的结构)
# 2 需要过滤的序列(可迭代结构)
# 返回值:过滤后的新序列(可迭代的结构)

# fn4 是作为参数传递进filter()函数中
# fn4 实际上只有一个左永刚,就是作为filter()的参数
# filter() 调用完以后,fn4 就已经没用
print(list(filter(fn4,l)))

# 匿名函数 lambda 函数表达方式
# lambda 函数表达式专门用来创建一些简单的函数,是函数创建的另外一种方式
# 语法:lambda 参数列表:返回值
# 一般都是作为参数使用
def fn5(a,b):
    return a + b
# print(lambda a,b : a+b)

# 也可以将匿名函数赋值给一个变量,一般不会这么做
fn6 = lambda a,b : a + b

r = filter(lambda i: i>5,l)
print(list(r))

# map() 函数可以对可迭代对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回

m = map(lambda i: i+1,l)
print(list(m))

# sort() 方法用来对列表中的元素进行排序
# 默认是直接比较列表中的元素大小
# 在sort() 可以接收一个关键参数,key
#  key 需要一个函数作为参数,当设置了函数作为参数
# 每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素大小
s = ['bb','aaa','c','ddddd','ddd']
# s = sort(key=len)
# print(s)

# sorted() 和sort() 用法基本一致,但是sorted()可以对任意的序列进行排序
#    并且使用sorted() 排序不会影响原来的对象,而是返回一个新对象
sd = [1,3,5,6,'4','7']
print('排序前:',sd)
print('sorted排序:',sorted(sd,key=int))



闭包

将函数作为返回值返回,也是一种高阶函数
这种高阶函数我们也称为闭包,通过闭包可以创建一些只有当前函数可以访问的变量
可以将一些私有的数据藏到闭包中


def fn():
    a = 10
    # 函数内部定义一个函数
    def inner():
        print('我是fn2',a)
    # 将内部函数 inner作为返回值返回
    return inner()
# r 是一个函数,是调用fn()后返回的函数
# 这个函数是在fn() 内部定义,并不是在全局函数
# 所以这个函数总是能访问到fn()函数内的变量
print(fn())
r = fn()

# 求多个数的平均值
nums = [59,4,53,57,85,34]
print(sum(nums)/len(nums))


# 形成闭包的必要条件
#     1 函数嵌套
#     2 将内部函数作为返回值返回
#     3 内部函数必须要使用到外部函数的变量

def make_averager():
    # 创建一个列表,用来保存数值
    num = []
    # 创建一个函数,用来计算平均值
    def averager(n):
        # 将n 添加到列表中
        num.append(n)
        # 求平均值
        return sum(num)/len(num)
    return averager
averager = make_averager()
print(averager(12))
print(averager(14))

装饰器

# 创建几个函数
'''
求任意两个数的和
'''
def add(a , b):
    r =  a + b
    return r
'''
求任意两个数的积
'''
def mul(a , b):
    r = a * b
    return r

# 希望函数可以在计算前,打印开始计算,计算结束后,打印计算完毕
'''
我们可以直接通过修改函数中的代码来完成这个需求,但是会产生下一个问题
1 如果要修改的函数过多,修改起来会比较麻烦
2 并且不方便后期的维护
3 会违反开闭原则(OCP)
    程序的设计,要求开发对程序的扩展(升级),要关闭对程序的修改(修改源代码)
'''
#r = add(123,345)
#print(r)

# 希望不修改原函数的情况下,对原函数进行扩展
def fn():
    print('我是fn函数。。。')

# 只需要根据现有的函数,来创建一个新的函数
def fn2():
    print('函数开始执行')
    fn()
    print('函数执行完毕')
fn2()

def new_add(a , b):
    print('函数开始执行')
    r = add(a , b)
    print('函数执行完毕')
    return r

r = new_add(23,34)
print(r)

# 上面的方式,已经可以在不修改源代码的情况下对函数进行扩展了
# 但是,这种方式要求我们每扩展一个函数就要手动创建一个新的函数,
#  为了解决这个问题,我们需要创建一个函数u,让这个函数㐓自动的帮助我们生产新函数
# 在定义函数时,可以通过@装饰器,来使指定的装饰器来装饰当前的函数

# 理解该函数的逻辑
def begin_end(old):
    '''
    用来对其他函数进行扩展,是其他函数可以在执行前开始执行,执行后打印执行结束
    参数:
        old要扩展的函数对象

    '''
    # 创建一个新函数
    def new_function(*args,**kwrgs):
        print('开始执行。。。。')
        # 调用被扩展的函数
        result = old(*args,**kwrgs)
        print('执行结束。。。。')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function(fn)


# f = begin_end(fn)
# r = f(123,456)
# print(r)
# 向begin_end()这种函数我们称他为装饰器
# 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
# 在开发中,我们都是通过装饰器来扩展函数的功能的
#


@begin_end
def say_hello():
    print('大家好')

say_hello()

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值