Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)

Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)

一,装饰器

 装饰器:本质就是函数,功能是为其它的函数动态添加附加的功能

原则:对修改关闭对扩展开放

1.不修改被修饰函数的源代码

2.不修改被修改函数的调用方式

 装饰器实现的知识储备:高阶函数,函数嵌套,函数闭包

## 高阶函数

# 高阶函数的定义:

1:函数接收的参数是一个参数名

2:函数的返回值是一个函数名

3:满足上述的任意一个条件,都可以称为高阶函数

一,函数接收的参数是一个参数名

def order():
    print("我是函数order")

def test(func):
    print(func)     # <function order at 0x000002AD351AD378>
    func()          # 我是函数order

test(order)         # 函数的实参是一个函数名,所以接收的参数是一个函数名

二,函数的返回值是一个参数名

# 下方程序不合格,函数会重复执行两次(order函数执行两次)
import time
def order():
    time.sleep(4)
    print("我是函数order")

def test(func):
    start_time = time.time()
    func()          # 我是函数order
    stop_time = time.time()
    print("函数 %s 的执行是将为%s " %(func,(stop_time - start_time)))
    return func     # 返回值为函数名

test_order = test(order)
test_order()        # 相当于执行函数 order

# 输出结果
我是函数order
函数 <function order at 0x0000029DBEA298C8> 的执行是将为4.035168170928955 
我是函数order

## 函数嵌套

## 函数闭包 

## 装饰器的架子

def timmer(func):
    def wrapper():
        print(func)
        func()
    return wrapper

 # 下方的程序解决了重复执行函数问题

# 下方程序的问题是:对所要计算执行时间的函数都得加上 test = timmer(test)

import time
def timmer(func):
    def wrapper():
        start_time = time.time()
        func()    # 运行的为test函数
        stop_time = time.time()
        print("程序运行的时间%s"%(start_time-stop_time))
    return wrapper


def test():
    time.sleep(3)
    print("test函数执行完毕")

test = timmer(test)    # 返回函数wrapper地址
test()    # 执行的时wrapper

# 结果
test函数执行完毕
程序运行的时间-3.000077962875366

## 语法糖

# @timmer 相当于 test = timmer(test)

# 当哪个函数需要加上装饰器,则在函数的上方加上@xxxx 语法糖

import time
def timmer(func):
    def wrapper():
        start_time = time.time()
        func()    # 运行的为test函数
        stop_time = time.time()
        print("程序运行的时间%s"%(start_time-stop_time))
    return wrapper

@timmer
def test():
    time.sleep(3)
    print("test函数执行完毕")

test()    # 执行的是wrapper

 

# 当被装饰的函数的参数变化时,装饰器的参数也得变化

import time
def timmer(func):
    def wrapper(name,age):
        start_time = time.time()
        func(name,age)    # 运行的为test函数
        stop_time = time.time()
        print("程序运行的时间%s"%(start_time-stop_time))
        print(name,age)
    return wrapper

@timmer
def test(name,age):
    time.sleep(3)
    print("test函数执行完毕")
test("henry",18)

@timmer
def test2(name,age,addr):
    time.sleep(3)
    print("test2函数执行完毕")
test2("heihei","16","China")
# 程序报错:当被装饰的函数有三个实参时,装饰器中也得有对应的形参

 

# 使用 *args,**kwargs解决,当被装饰的函数的参数变化时,装饰器的参数也得变化的问题

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)    # 运行的为test函数
        stop_time = time.time()
        print("程序运行的时间%s"%(start_time-stop_time))
        print(*args,**kwargs)
    return wrapper

@timmer
def test(name,age):
    time.sleep(3)
    print("test函数执行完毕")
test("henry",18)

@timmer
def test2(name,age,addr):
    time.sleep(3)
    print("test2函数执行完毕")
test2("heihei","16","China")    # 程序不在报错

# 输出
test函数执行完毕
程序运行的时间-3.000153064727783
henry 18
test2函数执行完毕
程序运行的时间-3.0007944107055664
heihei 16 China

 

## 浅浅了解*args与**kwargs

*args:将多个实参放入一个元组中,可以传多个参数

**kwargs:按照关键字传值,将多余的值以字典的形式传递

## *agrs

Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)
Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)

##  将实参与形参对应的按位置传值,多出来的给grgs
# 示例1
def test(a,*args):
    print(a)
    print(args)

test(1,2,3,4,5,6,7)
# 输出
1
(2, 3, 4, 5, 6, 7)

--------------------------------------------------------------

# 示例2(位置参数,默认参数,*args)
def test(a,b = 1 ,*args):
    print(a)
    print(b)
    print(args)

test(1,2,3,4,5,6,7)    # 1给了a,b=1的值被重置为2,其余的给了args
# 输出
1
2
(3, 4, 5, 6, 7)

-------------------------------------------------------------

# 示例3(位置参数,*args,默认参数)
def test(a,*args,b = 1 ):
    print(a)
    print(b)
    print(args)
test(1,2,3,4,5,6,7)
# 输出
1
1
(2, 3, 4, 5, 6, 7)

示例代码

 

 

 

## **kwargs(形参中按关键字传值,多余的以自定的形式传递)

Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)
Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)

# 示例1 将所有的值给了args
def test(*args,**kwargs):
    print(args)
    print(kwargs)
test(1,2,3,4,5)
# 输出
(1, 2, 3, 4, 5)
{}

---------------------------------------------------------

# 示例2
def test1(a,**kwargs):
    print(a)
    print(kwargs)
test1(1,b=2,c=3,d=4)
# 输出    将1给了a,将其余的以字典的形式给了Kwargs
1
{
     'b': 2, 'c': 3, 'd': 4}

-------------------------------------------------------

# 示例3
def test3(a,*args,**kwargs):
    print(a)
    print(args)
    print(kwargs)
test3(1,2,3,4,5,b=6,c=7)
# 输出
1
(2, 3, 4, 5)
{
     'b': 6, 'c': 7}

-----------------------------------------------------

# 错误示例
def test4(z,**kwargs,*args):
    print(z)
    print(kwargs)
    print(args)
test4(1,y=2,3,4,5)
# 报错 SyntaxError: invalid syntax

示例代码

小小补充:

num_l = [1,2,3,4,5,6,7,8]
a,*b,c = num_l
print(a)
print(b)
print(c)
# 输出
1
[2, 3, 4, 5, 6, 7]
8

注:
普通调换两个数
a = 1
b = 2
c = a
a = b
b = a

Python中的一一对应
a,b = b,a

## 携带参数的装饰器

import time
def timmer_test(file_type="aaa"):
    def timmer(func):
        def wrapper(*args,**kwargs):
            if file_type == "aaa":# 执行不同的功能
                print("携带的参数为aaa")
            elif file_type == "bbb":
                print("携带的参数为bbb")
            start_time = time.time()
            res = func(*args,**kwargs)    # 运行的为test函数
            stop_time = time.time()
            print("程序运行的时间%s"%(start_time-stop_time))
            return res
        return wrapper
    return timmer


@timmer_test(file_type="aaa")    # timmer = timmer_test(file_type="aaa") 最终的结果还是@timmer,已经附加一个file_type
def test1():
    time.sleep(3)
    print("test函数执行完毕")

@timmer_test(file_type="bbb")   # 携带不同的参数 执行不同的功能
def test2():
    time.sleep(2)
    print("test函数执行完毕")

test1()
test2()
# 输出
携带的参数为aaa
test函数执行完毕
程序运行的时间-3.0003297328948975
携带的参数为bbb
test函数执行完毕
程序运行的时间-2.00068998336792

 

转载于:https://www.cnblogs.com/Doaoao/p/10134718.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101252.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Oracle 904_oracle01017

    Oracle 904_oracle01017SQL>desceq_admin.its_earthquake_recover;名前NULL?型—————————————————————————–ORG_INF…

    2026年2月2日
    5
  • Linux学习——磁盘管理、用户管理、权限管理命令

    一:磁盘管理 df 查看磁盘大小 –h 1024 –H 1000 du 统计磁盘上文件的大小 — du -s /目录 — -h 1024显示二:用户管理 1 Linux中用户和用户组的概念 用户:使用操作系统的人,可以有很多的用户,运行多个用户同时操作一个系统 用户组:具有相同系统权限的一

    2022年2月26日
    44
  • Kali Linux更新及配置更新源

    Kali Linux更新及配置更新源默认状态下查看更新源root@kali2019:~#cat/etc/apt/sources.list更改Kali的更新源root@kali2019:~#vim/etc/apt/sources.list若更新源不可用,在执行apt-getupdate之后如下所示:更改为中科大更新源执行获取更新命令执行安装更新命令apt-getupdradekali官方源以…

    2022年5月28日
    41
  • 各种烦人图片的整理方法_凡人烦人

    各种烦人图片的整理方法_凡人烦人各种烦人图片资料的整理整合,也帮助自己进行一下梳理,有新的内容页会随时更新,大家看着图片烦恼的也可以看下,希望对和我一样的菜鸟有帮助哈!当然对于高手来说,您的回复是我勃起的动力首先还是要喊下口号———

    2022年8月4日
    6
  • 软件测试工作流程概括与总结[通俗易懂]

    软件测试工作流程概括与总结[通俗易懂]最近在为面试新工作做准备,所以想想整理一下软件测试的基本工作流程,大致梳理一遍,这样也便于自己在面试过程中可以沉着的面对面试管的测试工作如何进行的问题。首先,作为测试人员需要学习并了解业务,分析需求点为什么测试人员要参加需求分析?也就是进行测试需求分析的目的是什么?第一、把用户需求转化为功能需求:1)对测试范围进度量2)对处理分支进行度量3)对需求业务的场景进行度量…

    2022年6月7日
    37
  • 物业 小程序_智慧物业平台app安卓版

    物业 小程序_智慧物业平台app安卓版智慧小区小程序功能小区资讯展示小区最新的资讯和动态.让小区居民对小区的活动有全盘的了解.小区资讯详情.将对活动的具体情况.有一个更详尽的描述。物业通知由物业服务公司通过管理后台发布.能将最新的物业通知推送到用户手机桌面.实现物业管理信息的即时推送.点击即可查看详情。邮包提醒将以数字的方式,提醒住户有多少邮包在传达室尚未领取,领取完成后,该数字将自动归零。小区服务整合小区所有服务项目,如物业维修、超…

    2022年10月10日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号