IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 闭包和装饰器 -> 正文阅读

[Python知识库]闭包和装饰器

一、python闭包

1、生命周期

def outer():
    a = 10
    print(f"test {a}")
outer()

2、闭包要满足的条件

?	2.1、必须要有内嵌函数
?	2.2、内涵数必须要引用外函数的变量
?	2.3、外函数必须返回内函数
	示例:
		def outer(x):
		    a = 300
		    def inner():
		        print(x+a)
		    return inner
		d = outer(100)
		d()
		print(dir(d))
		#形成闭包之后,闭包函数就会得到一个非空的__closure__属性
		print(outer.__closure__,d.__closure__)

3、用闭包实例化的对象
.虽然代码都一样,但是创建的对象是不一样的,每次调用外函数都会重新执行,创建一个新的tmp_list和inner

def outer():
    tmp_list = []
    def inner(name):
        tmp_list.append(name)
        print(tmp_list)
    return inner
d1 = outer()
d1("d1")
d1('d1')
d2 = outer()
d2('d2')
d2("d2")

二、装饰器

1、装饰器的介绍

1.是一种程序设计模式,不改变函数或类的源代码基础上,添加额外功能
2.装饰器的本质就是闭包函数,它需要把一个callable(函数,类)对象作为参数传递进来

2、引出装饰器

#为了引出装饰器
import time
#时间戳:
	从1970到现在所经历的秒数
def func1():
    time.sleep(2)
    print("func1.........")

def func2():
    time.sleep(3)
    print("func2.........")
start = time.time()
func1()
end = time.time()
print(f"func1执行花了{end - start }秒")

start = time.time()
func2()
end = time.time()
print(f"func2执行花了{end - start }秒")

3、统计运行时间的装饰器

#除了主功能之外还实现了其他功能
import time
def runtime(func):
    def inner(*args,**kwargs):
        start = time.time()
        result = func(*args,**kwargs)	#让装饰器更加通用
        end = time.time()
        print(f"执行函数花了{end - start}秒")
        return result
    return inner
# @ 修饰符,去使用装饰器
@runtime    #func1 = runtime(func1)
def func1():
    time.sleep(2)
    print("func1.........")
    return "sanchuang"
@runtime
def func2(a,b):
    time.sleep(3)
    print("func2.........")
    print(f"fun2...{a}{b}")

result = func1()
print(result)
func2(1,2)

4、用装饰器实现权限控制

import functools
import time
def deco(name):
    def runtime(func):
        #保留传递进来的函数的原数据,将它的原数据赋值给inner
        @functools.wraps(func)
        def inner(*args,**kwargs):
            if name=="root":
                print("欢迎")
                print(f"func name is {func.__name__}")
                result = func(*args,**kwargs)
                return result
            else:
                return "没有权限"
        return inner
    return runtime

username = input("请输入你的用户名:")
@deco(name=username)
def add(a,b):
    time.sleep(3)
    return a+b
print(add(1,2))

三、装饰器的应用

1、可以应用多个装饰器去装饰函数,但是要注意装饰器的执行顺序
2、添加额外功能:计时、权限控制、日志记录等
3、案例:

import functools
import time
def runtime(func):
    #保留传递进来的函数的原数据,将它的原数据赋值给inner
    @functools.wraps(func)
    def inner(*args,**kwargs):
        start = time.time()
        result = func(*args,**kwargs)
        end = time.time()
        print(f"函数执行花了{end - start}s")
        return result
    return inner

def login_required(func):
    username = input("请输入你的用户名:")
    def inner(*args,**kwargs):
        if username=='root':
            print(f"欢迎执行{func.__name__}函数")
            result = func(*args,**kwargs)
            return result
        else:
            return "没有权限"
    return inner

@login_required
@runtime
def add(a,b):
    time.sleep(2)
    return a+b
result = add(1,2)
print(result)

@login_required
@runtime
def add2(a,b):
    time.sleep(3)
    return a+b
result1 = add2(1,2)
print(result1)

四、带参数的装饰器

1、自身不传入参数的装饰器,使用两层函数定义
2、自身传入参数的装饰器,使用三层函数定义

import functools
import time
def deco(name):
    def runtime(func):
        #保留传递进来的函数的原数据,将它的原数据赋值给inner
        @functools.wraps(func)
        def inner(*args,**kwargs):
            start = time.time()
            result = func(*args,**kwargs)
            end = time.time()
            print(f"函数执行花了{end - start}s")
            print(f"name is {name}")
            return result
        return inner
    return runtime

# runtime = deco(name = "sanle")
# func1 = runtime(func1)
@deco(name="sanle")
def func1():
    time.sleep(3)
    print("this is func1")
func1()

3、练习

	?装饰器带参数,来验证用户是否有权限运行函数
	运行add函数,运行前要判断有没有权限
?	判断一:用户名和密码是否正确			---用户名错误或密码错误
?	判断二:用户名是否为root,只有root用户有权限   		----输出用户没有权限
?	用户名和密码 通过带参传入
import functools
import time
def deco(name):
    def runtime(func):
        #保留传递进来的函数的原数据,将它的原数据赋值给inner
        @functools.wraps(func)
        def inner(*args,**kwargs):
            if name=="root":
                print("欢迎")
                print(f"func name is {func.__name__}")
                result = func(*args,**kwargs)
                return result
            else:
                return "没有权限"
        return inner
    return runtime

username = input("请输入你的用户名:")
@deco(name=username)
def add(a,b):
    time.sleep(3)
    return a+b
print(add(1,2))

五、属性包装 装饰器----property

property:把方法当作属性来使用

class Person():
    _age = 2
    @property   #property本身会创建另外两个装饰器,@age.setter  @age.deleter
    def age(self):
        return self._age
    @age.setter
    def age(self,num):
        if 0< num <120:
            self._age = num
        else:
            raise  ValueError("年龄不在范围")
p = Person()
print(p.age)
p.age = 110
print(p.age)

六、用类去实现装饰器

1、不带参数的装饰器用类实现

import time
class runtime:
    def __init__(self,func):
        self.func = func
    def __call__(self,*args,**kwargs):
        start = time.time()
        result = self.func(*args,**kwargs)
        end = time.time()
        print(f"运行函数{self.func.__name__}花费了{end - start}秒")
        return result

@runtime
def func1(a,b):
    print("this is func1......")
    time.sleep(2)
    return a+b
print(func1(1,2))

2、带参数的装饰器用类实现

import time
class runtime:
    def __init__(self,name):
        self.name = name
    def __call__(self,func):
        def deco(*args,**kwargs):
            start = time.time()
            result = func(*args,**kwargs)
            end = time.time()
            print(f"运行函数{func.__name__}花费了{end - start}秒")
            return result
        return deco

@runtime("name")
# a1 = runtime("name")
# func1 = a1(func1)
def func1():
    time.sleep(2)
    print("this is func1......")

func1()

七、装饰类

def outer(cls):
    def inner(*args,**kwargs):
        print(f"class name is:{cls.__name__}")
        return cls(*args,**kwargs)
    return inner

@outer  # A = outer(A)
class A:
    def __init__(self,name):
        self.name = name
print(type(A))
m = A("sc")
print(m.name)
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:40:12  更:2022-08-06 10:42:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 15:56:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码