首页 > 编程语言 >【Python查漏补缺(一)】闭包和装饰器

【Python查漏补缺(一)】闭包和装饰器

时间:2023-06-08 23:03:55浏览次数:45  
标签:闭包 查漏 函数 Python sum num result print def


闭包的构成条件:

  1. 在函数嵌套(函数里面再定义函数)的前提下

  2. 内部函数使用了外部函数的变量(还包括外部函数的参数)

  3. 外部函数返回了内部函数

简单闭包

def fun_out(num1):
   # 定义外部函数
   def fun_inner(num2):
       # 内部函数使用了外部函数的变量
       result = num2 + num1
       print("结果是: ", result)
   # 外部函数返回了内部函数,这里返回的内部函数就是闭包
   return fun_inner
 
f = fun_out(1)  # 创建闭包实例

f(2)
f(3)
  1. 当返回的内部函数使用了外部函数的变量就形成了闭包

  2. 闭包可以对外部函数的变量进行保存

闭包的作用

*闭包的作用: 闭包不仅可以保存外部函数的变量还可以提高代码的可重用性(不需要再手动定义额外的功能函数*

def config_name(name):  # 定义外部函数
   # 内部函数使用了外部函数的变量
   def say_info(info):
       print(name + ":" + info)

   return say_info

tom = config_name("Tom")
tom("你好!")
tom("你好,在吗?")

jerry = config_name("jerry")
jerry("不在,不和你玩!")

 

装饰器的功能特点:

  1. 不修改已有函数的源代码

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

  3. 给已有函数增加额外的功能

def check(fn):
   # 追加一个登陆验证的功能
   def inner():
       print("请先登陆!")
       fn()
   return inner


def comment():
   print("发表评论!")


comment = check(comment)
comment()
  • 闭包函数有且只有一个参数,必须是函数类型,这样定义的函数才是装饰器。

  • 写代码要遵循开放封闭原则,它规定已经实现的功能代码不允许被修改,但可以被扩展。

装饰器的语法糖写法

如果有多个函数都需要添加登录验证的功能,每次都需要编写func = check(func)这样代码对已有函数进行装饰,这种做法还是比较麻烦。

Python给提供了一个装饰函数更加简单的写法,那就是语法糖,语法糖的书写格式是: @装饰器名字,通过语法糖的方式也可以完成对已有函数的装饰

糖写法演示

@check
def comment():
   print("发表评论")

@check ==> comment = check(comment)

使用装饰器添加登陆验证功能

def check(fn):
   print("装饰函数执行了")
   def inner():
       print("请登陆....")
       fn()
   return inner

@check    # @check 等价于 comment = check(comment)
def comment():  # 装饰器的执行时间是加载模块时立即执行。
   print("发表评论!")

comment()  # 调用函数

 

使用装饰器对函数执行时间进行统计

import time

def get_time(func):
   # 定义函数的嵌套,
   def inner():
       begin_time = time.time()
       func()   # 内部函数使用了外部函数的变量包括参数
       end_tiem = time.time()
       print("函数执行花费了:%f" % (end_tiem-begin_time))
       print("测试:",end_tiem-begin_time)
   return inner  # 外部函数返回了内部函数


@get_time   # 等价于test = get_tiem(test)
def test():
   for i in range(10000000):
       i += 1
   print(i)

test()

带有不定长参数的装饰器

*args和**kwargs都是可变长度参数的方式

*args:用于传递不定数量的位置参数,它会将所有的位置参数打包成一个元组(tuple)。

**kwargs:用于传递不定数量的关键字参数,它会将所有的关键字参数打包成一个字典(dictionary)。

def logging(fun):  # 这里fun = sum_num
   # *args和**kwargs都是可变长度参数的方式,它们之间的区别如下:
   #
   # *args:用于传递不定数量的位置参数,它会将所有的位置参数打包成一个元组(tuple)。
   #
   # **kwargs:用于传递不定数量的关键字参数,它会将所有的关键字参数打包成一个字典(dictionary)。
   def inner(*args, **kwargs):
       print("--正在努力计算--")
       fun(*args, **kwargs)  # 调用sum_num
   return inner

@logging  # 这里sum_num = logging(sum_num)
# 执行到这里就有 sum_num = inner
def sum_num(*args, **kwargs):
   result = 0
   for vaules in args:  # args元组形式
       result += vaules

   for vaules in kwargs.values():  # kwargs将所有参数转化为字典类型的数据
       result += vaules

   print(result)

sum_num(1, 2, a=10)

通用装饰器

# 通用装饰器
def logging(fn):  # 2,将函数sum_num 作为参数传递
   def inner(*args, **kwargs):
       print("--正在努力计算--")
       result = fn(*args, **kwargs) # fn = sum_num, fn = subtraction
       return result

   return inner


# 使用语法糖装饰函数
@logging  # 1 这里sum_num = logging(sum_num) -- 之后sum_num = inner,调用sum_num相当于调用inner
def sum_num(*args, **kwargs):
   result = 0
   for value in args:
       result += value

   for value in kwargs.values():
       result += value

   return result


@logging  # 3,这里subtraction = logging(subtraction) 之后subtraction = inner,调用subtraction相当于调用inner
def subtraction(a, b):
   result = a - b
   print(result)

result = sum_num(1, 2, a=10)  # 调用sum_num 函数即调用inner函数,其中fun()为sum_num()本体
print(result)

subtraction(4, 2)
 

标签:闭包,查漏,函数,Python,sum,num,result,print,def
From: https://www.cnblogs.com/liam-sliversucks/p/17467906.html

相关文章

  • 【Python查漏补缺(二)】正则表达式与深浅拷贝
    在开始正题之前讲一下打开文件的另一种方式。之前打开文件的方式f=open("文件路径","文件打开方式",encoding="utf8")模式描述r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开......
  • 【Java查漏补缺(一)】数组与循环
    除了数组与循环,还有方法,讲究看吧!后续练习内容都是连贯的!BasicalJava看下Java中的变量类型吧!数据类型关键字内存占用二进制位数字节型byte1个字节4位短整型short2个字节8位整型int(常用)4个字节32位长整型long8个字节64位单精度浮点数float......
  • 【视频】Python的天气数据爬虫实时抓取采集和可视化展示
    全文链接:http://tecdat.cn/?p=32715原文出处:拓端数据部落公众号分析师:XiaoyangZhou本文以天气数据实时抓取和可视化展示为主题,旨在探讨如何使用Python编写程序来实现对天气数据的抓取、可视化和预测。从中国气象局天气预报网来获取数据首先,我们需要从中国气象局天气预报网上......
  • python爬虫——爬取网易云音乐评论内容
    一、选题背景  随着互联网的快速发展,网络上的评论文本资源急速增长。面对海量的网络资源信息,如何运用python爬虫技术爬取数据进行数据分析,挖掘评论文本中蕴含的丰富价值。二、大数据分析设计方案1.爬虫网站https://music.163.com/?from=wsdh#/song?id=2052441038 ......
  • 实验6turtle绘图与python库应用编程体验
    实验任务1test1实验代码fromturtleimport*defmove(x,y):penup()goto(x,y)pendown()defdraw(n,size=100):foriinrange(n):fd(size)left(360/n)defmain():pensize(2)pencolor('red')move(-200,0)......
  • Python取整及四舍五入
    向上取整:math.ceil()importmathmath.ceil(-0.9)>>>0math.ceil(0.3)>>>1向下取整:math.floor()、int()、//(整除)math.floor(-0.3)>>>-1int(0.9)>>>03//2#1.5>>>1虚假的四舍五入:round()""&quo......
  • 14dayPythonTask7-类与对象+魔法函数
    目录类与对象1.对象=属性+方法2.self是什么?3.Python的魔法方法4.公有和私有5.继承6.组合7.类、类对象和实例对象8.什么是绑定?9.一些相关的内置函数(BIF)练习题魔法方法1.基本的魔法方法2.算术运算符3.反算术运算符4.增量赋值运算符5.一元运算符6.属性访问7.描......
  • 【python】lambda
    lambdalambda是匿名函数,也就是没有名字的函数。lambda的语法非常简单:下面是一个lambda表达式的简单例子,我们可以把lambda表达式赋值给一个变量,然后通过这个变量来使用它:>>>my_sum=lambdax,y:x+y>>>my_sum(1,2)3lambda默认参数详解语法lambda[parameter_list,p......
  • python常用函数(zip,map,filter,reduce)
    一、zip它是Python的内建函数,(与序列有关的内建函数有:sorted()、reversed()、enumerate()、zip()),其中sorted()和zip()返回一个序列(列表)对象,reversed()、enumerate()返回一个迭代器(类似序列)>>>name=('jack','man','sony','pcky')>>>age=(2001,2003,2005,......
  • python 中输出匹配字符串及其下一行
     001、[root@PC1test05]#lsa.txttest.py[root@PC1test05]#cata.txt##测试数据3333gene9999kkkkgene77778888genegene00006666[root@PC1test05]#cattest.py##测试程序#!/usr/bin/envpython#-*-coding:utf-8-*-in_file=open("a.tx......