Python基础 06----函数进阶(匿名函数, 装饰器)

递归函数

  • 递归函数 自己调用自己,必须要找到函数停止的条件
# 递归 函数内部自己调用自己
# 递归的关键是找到程序的出口(程序停止的条件)
# 使用count 计数器
count = 0


def tell_story():
    global count
    count += 1
    print('hello world')
    if count < 5:
        tell_story()


tell_story()


# 求 n 个数的和
def get_sum(n):
    if n == 0:
        return 0
    return get_sum(n - 1) + n

# 关键是要停下来
print(get_sum(6))

匿名函数

  • 用来表示简单的函数,调用次数很少
  • 省略了需要 def 声明函数部分

语法

  • lambda 参数列表:运算符表达式
def add(a, b):
	return a + b


x = add(2, 5)

fn = add  # 相当于给函数fn 起一个别名
print(fn(2, 3))

# lambda  定义一个函数
# 匿名函数  用来表示简单的函数,调用次数很少基本上只用一次

# 调用匿名函数的方式
# 1.给他定义一个名字(很少使用)
mul = lambda a, b: a + b
print(mul(2, 3))

使用场景

把匿名函数当作参数传递给另一个函数

# 2.把匿名函数当作一个参数传递给另一个函数使用(使用场景比较多)
def add(a,b):
	print(a, b)
def clc(a, b, obj):
	print(a, b, obj)


obj = lambda a, b: add(a, b)
clc(1, 2, (3, 4))

高阶函数

  • 把函数当成数字和字符串使用
  • 一个函数当作另一个函数的参数
  • 函数作为返回值
  • 函数中写另一个函数

# 1.一个函数作为另一个函数的参数
# 2.一个函数作为另一个函数的返回值
# 3.在一个函数中写另一个函数

def foo():
    print(1)
    return 'foo'


def bar():
    print(2)
    return foo


x = bar()
print('x的值是{}'.format(x))

print('-----------------')
x()

bar()()  # 调用bar · bar再调用foo

def outer():
    m = 100

    def inner():
        n = 98
        print('我是inner函数')

    inner()
    print('我是outer函数')
    return inner


# inner()函数在外部不能使用
outer()()  # 先调用outer 再在outer内部调用inner

闭包的使用

  • 闭包函数 = 名称空间与作用域+函数嵌套+函数对象
def outer(n):
    num = n
    def inner():
        return num+1
    return inner

print(outer(1)())  # 2
print(outer(5)())  # 6

闭包函数定义:在一个函数中包含一个函数对其作用域的外部变量的引用,那个对外部函数引用的函数为闭包

# 1.大前提
# 闭包函数 = 名称空间与作用域+函数嵌套+函数对象
# 核心点:名字的查找关系是以函数定义阶段为准的

# 2.什么是闭包函数
# 闭 指函数定义在一个函数内的函数(内嵌函数)
# 包 指函数对包含在外层的函数的作用域的名字的引用
#       (不包含全局作用域)

# 闭包函数之名称空间的与作用域的应用 + 函数嵌套
# def f1():
#     x = 1
#     def f2():
#         print(x)
#     f2()
# x = 222
# def bar():
#     x = 3344
#     f1()
#
# bar()


# 闭包函数 :函数对象(以定义阶段为主)
# def f1():
#     x = 1
#     def f2():
#         print('f2的输出',x)
#     f2()
#
#     return f2  # 返回f2的内存地址
#
# f = f1()
#
# x = 444
# f()


# 3.定义闭包函数

# 4.为何要有闭包函数(闭包函数的应用)
# 两种函数传参方式

# 方式一: 直接把函数体需要的参数定义形参
# def f1(x):
#     print(x)
# f1(1)

# 方式二:
def f1():
    x = 3

    def f2():
        print(x)

    # f2(x)
    return f2


# f2()

f = f1()
f()

  • 修改闭包函数中的外部变量 使用 nonlocal函数
def outer(n):
    num = n
    def inner():
        nonlocal num  # 修改前使用nonlocal关键字对 num 变量进行说明
        num = num + 1
        return num
    return inner

print(outer(2)())

装饰器的使用

# -*- coding: utf-8 -*-
# @Time    : 2021/1/25 21:26
# @File    : 装饰器.py
# @Software: PyCharm

# def foo():
# 	print('foo')
#
#
# foo()  # foo
# print(foo)  # <function foo at 0x0000027802C19EE0>

# def foo():
# 	print('foo')
#
#
# foo()  # foo
# foo = lambda x: x + 1
# # 把匿名函数赋值给foo之后,原本的函数的内存地址改变为新赋值的
# print(foo)  # <function <lambda> at 0x000001C667759A60>


# 开发中要遵循 开放封闭原则
# 封闭 对以开发的功能封闭
# 开放 对扩展的功能开放

# def w1(func):
#     def inner():
#         # 验证1
#         # 验证2
#         # 验证3
#         func()
#     return inner
#
# @w1
# def f1():
#     print('f1')
# @w1
# def f2():
#     print('f2')
# @w1
# def f3():
#     print('f3')
# @w1
# def f4():
#     print('f4')
# def w1(func):
# 	def inner():
# 		# 验证1
# 		# 验证2
# 		# 验证3
# 		func()
#
# 	return inner
#
#
# @w1
# def f1():
# 	print('f1')


# print(f1)  # <function w1.<locals>.inner at 0x0000026A3596E4C0>
# 此地址为添加装饰器之后的地址

# @ w1    执行 w1函数, 将 w1下的函数当作参数传递给 w1()函数中的func
# @ w1  ==> w1(f1)
# 此时的func = f1    func() = f1()


def makeBoid(func):
	def wrapper():
		return '<b>' + func() + '</b>'
	
	return wrapper


def makeIctlin(func):
	def wrapper():
		return '<a>' + func() + '</a>'
	
	return wrapper


@makeIctlin
def test1():
	return '111111'


@makeBoid
def test2():
	return '222222'


@makeBoid
@makeIctlin
def test3():
	return '3333333'


print(test1())
print(test2())
print(test3())

# <a>111111</a>
# <b>222222</b>
# <b><a>3333333</a></b>

装饰器(decorator)功能

  • 引入日志
  • 函数执行时间统计
  • 执行函数前预备处理
  • 执行函数后清理功能
  • 权限校验等场景
  • 缓存

无参装饰器

# 无参装饰器
def check(func):
	def wrapper():
		return '早点' + func()
	
	return wrapper


@check
def go_to_bed():
	return '去睡觉'


print(go_to_bed())
# 早点去睡觉

被装饰的函数有参数

def check(func):
	def wrapper(name, action):
		return '我说' + func(name, action)
	return wrapper


@check
def go_to_bed(name, action):
	return name + '去睡觉' + action


print(go_to_bed('张三', '在家'))
# 我说张三去睡觉在家

被装饰的函数有不定长参数

def check(func):
	def wrapper(*args, **kwargs):
		return func(*args, **kwargs)
	
	return wrapper


@check
def demo(*args):
	sum = 0
	for i in args:
		sum += i
	print(sum)


print(demo(1, 2, 3))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值