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)
上一篇 2021年6月18日 下午6:00
下一篇 2021年6月18日 下午7:00


相关推荐

  • Linux进程和计划任务管理

    Linux进程和计划任务管理

    2021年9月6日
    58
  • 散列/散列函数「建议收藏」

    散列/散列函数「建议收藏」散列是一种用于以常数平均时间执行插入、删除和查找的技术。每个关键字被映射到从0-TableSize-1这个范围中的某个数,并且被放到适当的单元中。这种映射就叫做散列函数我认为,先用散列函数将我们所要进行操作的集合整合成散列表,是对之后的操作的一种便利。放到实际中去,我们要进行操作的集合不仅仅只是数字,例如图书馆中的书籍分类等等。而且就算是一组不连续差距较大的数字,要执行后序的插入删除和查找都是很不方

    2022年5月15日
    44
  • Mybatis实现Oracle 分页「建议收藏」

    Mybatis实现Oracle 分页「建议收藏」Mybatis+Oracle分页1,使用mybatis的插件PageHelper(1)Mapper.xml<?xmlversion=”1.0″encoding=”UTF-8″?><!DOCTYPEmapperPUBLIC”-//mybatis.org//DTDMapper3.0//EN””http://mybatis.org/dtd/mybati…

    2022年5月28日
    302
  • Python模块——hashlib

    Python模块——hashlib简介 hashlib 模块是用于对字符串进行加密 其可以把任意长度的数据转换为一个长度固定的数据串 且这种加密是不可逆的 故这种加密方式的安全性都很高 hash 本质是一个函数 该模块提供了许多不同的加密算法 可查看其属性 algorithms guaranteed 来获取 包括 md5 sha1 sha224 sha256 sha384 sha512 使用非常简单 方便 该模块由 python 自

    2026年3月17日
    2
  • 十大思维导图软件推荐

    十大思维导图软件推荐1 GitMindGitMi 是一款电脑上好用的免费在线思维导图软件 主要功能有大纲视图 一键自动布局 多人云协作 插入富文本 批量管理文件 格式刷 自定义主题 快速查看历史版本 插入关系线 添加概括 一键分享思维导图 多格式文本导出 电脑手机云同步等等 可用来轻松制作思维导图 逻辑结构图 业务流程图 UML 图 组织架构图 拓扑图以及数据流图等等 适用于做读书笔记 项目规划 会议记录以及头脑风暴 产品规划等 主要特点 免费无广告 简单易上手支持自由设计主题样式和风格可以导出 PD

    2026年3月18日
    2
  • Spug – 轻量级自动化运维平台

    Spug – 轻量级自动化运维平台Spug-轻量级自动化运维平台对于中小型企业而言,进行主机和应用的管理是比较麻烦的,应用部署往往需要直接连接服务器,再进行手动的环境配置、代码拉取、应用构建和部署发布等工作,容易出错,且耗时费力。一个好的自动化运维平台,往往能大大节省人力物力,提高开发部署效率。Spug,正是一个面向中小型企业设计的轻量级自动化运维平台。Spug自动化运维平台简介Spug,是openspug在Github上开源的自动化运维平台,项目位于https://github.com/openspug/spug,

    2022年5月17日
    114

发表回复

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

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