Python基础——高阶函数

本文详细介绍了Python编程中的高阶函数,包括函数作为参数和返回值,函数嵌套;深入探讨了列表推导式的使用,如何创建平方数列表和分组列表;解释了闭包的概念;详细阐述了装饰器的运用,包括带参数的装饰器以及权限验证的实现;最后,提到了匿名函数lambda的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、列表推导式

  • 所谓的列表推导式,就是指的轻量级循环创建列表;
  • 语法:指定一个描述性的列表名,如element;然后指定一个列表[ ],并在列表中定义一个表达式,如value**2,计算平方值;再写一个for循环,用于给表达式提供值for value in range(1,6)
# 1)for循环——打印一个列表
a = []
for i in range(10):
    a.append(i)
print(a)

# 2)用列表推导式
a = [x for x in range(10)]
print(a)
# 2、创建平方数列表
a = [x for x in range(1, 6)]
print(a)

b = [i ** 2 for i in a]
print(b)
# 3、c是一个列表 ,列表中元素为元组
c = [(x, y) for x in range(3) for y in range(5)]
print(c)
# 4、实现分组一个list的元素,如[1, 2, 3,...100]变成[[1, 2, 3], [4, 5, 6]...]
x = [i for i in range(1, 101)]
y = [x[i:i + 3] for i in range(0, 100, 3)]  # 需要取步长,否则结果不正确i=0==>[0:3]  i=3===>x[3:6]
print(y)

二、高阶函数

1、函数作为另一个函数的参数、返回值(高阶函数)

  • 1)函数既然和数字、字符串等一样,也是一种数据类型,它能像数字和字符串一样当做另一个函数的参数;
  • 2)函数也能当做另一个函数的返回值
def get_sum(n):
    result = 0
    for i in range(n + 1):
        result += i
    return result

print(type(get_sum))  # <class 'function'>
fn = get_sum
print(get_sum(100))
print(fn(20))
# 2、函数当做另一个函数的返回值
def test():
    print('我是test函数')
    print('test函数有返回值,返回值是1')
    return 1

def demo():
    print('我是demo函数')
    print('demo函数有返回值,返回值是test这个函数的执行结果')
    return test()  # 加括号时才调用函数

def foo():
    print('我是foo函数里的代码')
    print('foo的返回值是test函数')
    return test

x = demo()
print(x) # 1

# foo函数的返回值也是一个函数
y = foo()
print(y)  # 不会调用test函数,只返回test函数<function test at 0x000001AB9243FD08>

# 可以调用这个函数
z = y()
print(z)  # 1,会调用test函数

foo()() # 1,会调用test函数

2、函数嵌套函数

  • 1)global value # 用于全局变量;
  • 2)nonlocal value # 使用nonlocal关键字修改外部函数的局部变量
def outer():
    a = 100  # 局部变量
    b = 'hello'
    print('我是outer内,inner外的代码')

    def inner():
        a = 200
        # global b 用于全局变量
        nonlocal b  # 使用nonlocal关键字修改外部函数的局部变量
        b = 'good'
        print('inner内部变量a的值是%d' % a)  # 200
        print('inner内部变量b的值是%s' % b)  #
        print('我是inner内的代码')

    inner()
    print('outer里变量a的值是%d' % a)  # 100
    print('outer里变量b的值是%s' % b)  # good(加了nonlocal b后,b的值由hello修改为good)

outer()  # 只打印outer
# inner()  # inner函数是在函数内部定义的,在函数外部不能访问

三、闭包

  • 有了嵌套函数这种结构,便会产生闭包问题;
  • 闭包:由函数及其相关的引用环境组合而成的实体(即:闭包=函数块+引用环境);
    如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
def outer():
    a = 'hello'  # 局部变量

    def inner():
        print(a)  # 内部函数使用了局部变量

    return inner()  # 返回内部函数

outer()() # hello

四、装饰器

1、装饰器的基本使用

  • @cal_decorator # 会调用cal_decorator这个函数,并把函数名传递给cal_decorator的参数(即把test传给fn);
  • 先搭框架,然后再写逻辑,如下,1)先把do_action( )函数写出来;2)play_game()有参数,则def can_play( fn ),fn参数就是play_game()函数;3)play_game()调do_action( ),play_game()给参数了,则do_action( )需要接收参数
def can_play(fn):
    def do_action(clock):
        pass

    return do_action

@can_play
def play_game():
    print('正在玩游戏')

play_game(22)
# 1、多个函数均调用同一段代码
import time

def test():
    print('hehe')
    time.sleep(3)
    print('hahahahaha')

# time.time()拿到是时间戳,从1970-1-1 8:00:00 UTC+8开始,到现在的秒数
# print(time.time())
start = time.time()
test()
end = time.time()
print(end - start)

def demo():
    y = 0
    for x in range(10000):
        y += x

start = time.time()
demo()
end = time.time()
print(end - start)
# 2、多个函数均调用同一段代码——将该段代码封装成一个函数进行调用
import time

def cal_time(fn):
    start = time.time()
    fn()
    end = time.time()
    print(end - start)

def test():
    print('hehe')
    time.sleep(3)
    print('hahahahaha')
cal_time(test)
# 3、多个函数均调用同一段代码——使用装饰器
import time

def cal_decorator(fn):
    def do_action():
        start = time.time()
        fn()
        # x = fn()
        end = time.time()
        print('{}函数耗时{}'.format(fn, end - start))
        # return x
    return do_action

@cal_decorator # 会调用cal_decorator这个函数,并把函数名传递给cal_decorator的参数(即把test传给fn)
def test():
    print('hehe')
    time.sleep(3)
    print('hahahahaha')

test() #调用装饰器
# cal_decorator(test)() #注释装饰器后,执行cal_decorator()函数

@cal_decorator
def demo():
    y = 0
    for x in range(10000):
        y += x
    return y
    
demo() # 本质上调用的其实是do_action(),demo不再是之前的那个函数,而是装饰器内部的那个函数do_action
print('demo=={}'.format(demo)) # demo==<function cal_decorator.<locals>.do_action at 0x00000214092140D0>

result = demo()
print(result)  # 返回None,因为demo()本质上调用的其实是do_action()

2、被装饰的函数有参数

  • 如果被装饰的函数有参数,则在内部函数里面将参数写上,且一般会加上*args, **kwargs,进行功能扩展
# 1、将字符串首字母大写,使用装饰器
def capital_word(fn):
    def do_action(x):
        return x.capitalize()

    return do_action

@capital_word
def test(word):
    # return word.capitalize()
    return word

result = test('hell world')  # 此时调的test()就是do_action(),就需要写do_action()里面的逻辑
print(result)  # Hello world
# 2、装饰器扩展函数功能
def can_play(fn):
    def do_action(clock):
        if clock < 20:
            fn()
        else:
            print('太晚了,不能玩了,赶紧睡!')

    return do_action

@can_play
def play_game():
    print('正在玩游戏')

# play_game()没有参数,但是play_game(22)给了参数
play_game(22)
play_game(19)
# 3、装饰器扩展函数功能
def can_play(fn):
    def do_action(name, game, *args, **kwargs):
        if kwargs.get('clock', 20) < 21:
        # if args[0] < 21:
            fn(name, game)
        else:
            print('时间太晚了,超过21:00,不能玩了!')

    return do_action

@can_play
def play_game(name, game):
    print(name + '正在玩' + game)

play_game('张三', '王者荣耀') # 没传后面的参数,默认是20:00,让玩游戏
play_game('李四', '和平精英', clock=20) # 写了一个关键字参数
play_game('李四', '和平精英', 22) #给可变参数*args

3、装饰器带参数

  • 架构搭好,三层嵌套函数
clock = int(input('请输入时间:'))

def can_play(clock):
    def handle_action(fn):
        def do_action(name, game, *args, **kwargs):
            if clock < 21:
                fn(name, game)
            else:
                print('太晚了,超过21:00,不能玩了')

        return do_action

    return handle_action

@can_play(clock) #@can_play(21)  21给can_play(clock)中clock
def play_game(name, game):
    print(name + '正在玩' + game)

play_game('张三', '王者荣耀')
play_game('李四', '和平精英')

五、权限验证

1、读写执行权限验证

  • 一般会先给定一些数来表示可以做的相应的行为,称为权限因子;
  • 如果需要给定最高权限,可在数据库里把权限给到最大
PERMISSION_READ = 4  # 0b100
PERMISSION_WRITE = 2  # 0b010
PERMISSION_EXE = 1  # 0b001

user_permission = 5  # ob101(=4+1 可读可执行)
# 通过修改用户已指定的权限,如给定5

def check_permission(permission):
    def handle_action(fn):
        def do_action():
            if user_permission & permission != 0:  # (5&4)
                fn()
            else:
                print('对不起,您没有相应的权限')

        return do_action

    return handle_action

@check_permission(PERMISSION_READ)
def read():
    print('我正在读取内容')

@check_permission(PERMISSION_WRITE)
def write():
    print('我正在写入内容')

@check_permission(PERMISSION_EXE)
def execute():
    print('我正在执行内容')


read()
write()
execute()

2、发帖评论留言回复删除权限

PERMISSION_SEND = 1
PERMISSION_COMMENT = 2
PERMISSION_MESSAGE = 4
PERMISSION_REPLY = 8
PERMISSION_DELETE = 16

user_permission = 23  # (=1+2+4+16)


def check_permission(x):
    def handle_action(fn):
        def do_action():
            if user_permission & x != 0:
                fn()
            else:
                print('您没有相应定权限!')

        return do_action

    return handle_action

@check_permission(PERMISSION_SEND)
def send():
    print('我可以发帖啦!')

@check_permission(PERMISSION_COMMENT)
def comment():
    print('我可以评论啦!')

@check_permission(PERMISSION_MESSAGE)
def message():
    print('我可以留言啦!')

@check_permission(PERMISSION_REPLY)
def reply():
    print('我可以回复啦!')

def delete():
    print('我可以删贴啦!')


send()
comment()
message()
reply()
delete()

六、补充(匿名函数的使用)

fns = [lambda x: x * i for i in range(3)]

for fn in fns:
    print(fn(5)) # 打印3遍10
fns = []
for i in range(3):
    fns.append(lambda x: x * i)
# lambda表达式是个函数
# fns = [lambda x: x * i, lambda x: x * i, lambda x: x * i]

print(fns[0](5)) # 10
print(fns[1](5)) # 10
print(fns[2](5)) # 10
def demo(x):
    return x * i


for i in range(3):
    # fns.append(demo)
    print('hehe')

print(i)  # i=2
print(demo(5))  # 10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值