python高级语法--闭包、装饰器

1、property属性

1.1、定义

property属性就是负责把类中的一个方法当作属性进行使用,可以简化代码

1.2、装饰器方式

class Person(object):
    def __init__(self):
        self.__age =0
        
    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,new_age):
        self.__age = new_age

p=Person()
print(p.age)
p.age=100
print(p.age)

1.3、类属性方式

property的参数

第一个参数是获取属性是要执行的方法

第二个参数是设置属性时要执行的方法

定义property属性有两种方式:1、装饰器方式 2、类属性方式

装饰器方式:1、property修饰获取值的方法

​ 2、@方法名。setter修饰设置值的方法

类属性方式

​ 1、property属性=property(获取值方法,设置值方法)

class Person(object):
    def __init__(self):
        self.__age = 0

    def get_age(self):
        return self.__age

    def set_age(self,new_age):
        if new_age>=150:
            print("年龄错误")
        else:
            self.__age=new_age
    age = property(get_age,set_age)

p=Person()
print(p.age)
# 设置属性
p.age=100
print(p.age)

2、with语句

python提供了with语句用于简化资源释放的操作,使用with语句操作建立在上下文管理器(实现 __ enter __ 和 __ exit __ 方法)的基础上

class File(object):
    def __init__(self,file_name,file_model):
        self.file_name = file_name
        self.file_name= file_model
    def __enter__(self):
        print("这是上文")
        self.file = open(self.file_name,self.file_model)
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("这是下文")
        self.file.close()

with File("1.txt","r") as f:
    file_data=f.read()
    print(file_data)

3、生成器

3.1、作用

根据程序设计者指定的规则循环生成数据,当条件不成立时则生成数据结束。

数据不是一次性全部生成出来,而是使用一个,再生成一个,可以节约大量的内存

3.2、生成器推导式

与列表推导式类似,只不过生成器推导式使用小括号

data = (x for x in range(100))
next(data)

for i in data:
    print(i)

生成器相关函数

next函数获取生成器中的下一个值

for循环遍历生成器中的每一个值

3.3、yield关键字

yield关键字生成器的特征:在def函数中具有yield关键字

def mygenerater(n):
    for i in range(n):
        print('开始生成....')
        yield
        print('完成一次.....')
g= mygenerater(5)
# print(next(g))
# print(next(g))
# print(next(g))

for i in g:
    print(i)

1、代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行

2、生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration异常,表示停止迭代异常

3、while循环内部没有处理异常操作,需要手动添加处理异常操作

4、for 循环内部自动处理了停止迭代异常,使用起来更加方便,推荐使用

3.4、生成器产生斐波纳锲数列

(前面两个数字相加) 1、2、3、5、8、13、21.。。。。。

def fb(num):
    a =0
    b=1
    index =0
    while index< num:
        result = a
        a,b = b,a+b
        yield result
        index +=1
f=fb(8)
for i in f:
    print(i)

1、生成器时根据算法生成数据的一种机制 ,每次调用生成器只生成一个值,可以节省大量内存

2、生成器的创建

4、深拷贝和浅拷贝

copy函数时浅拷贝,只对可变类型的第一层对象进行拷贝

对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象

4.1、可变类型浅拷贝

#普通赋值
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=c
print(id(d))
print(id(c))

#浅拷贝可变类型
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(d))
print(id(c))

#浅拷贝、深层数据
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

#浅拷贝不可变类型
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

4.2、深拷贝

对每一层拷贝对象都会开辟新的内存空间进行存储

# 深拷贝,可变数据
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.deepcopy(c)
# print(id(a))
print(id(c))
print(id(d))

# 深拷贝,深层数据
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.deepcopy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

#深拷贝不可变类型

import copy
a =(1,2,3)
b=(11,22,33)
c =(a,b)
d=copy.deepcopy(c)
print(id(c))
print(id(d))

5、函数参数

​ 作用:1、函数名存放的是函数所在空间的地址

​ 2、函数名()执行函数名所存放空间地址中的代码

​ 3、如下func01=func02函数名可以像普通变量一样赋值,func01()等价于func0()

def func01():
    print("func01 is show")

def foo(func):
    func()
foo(func01)

6、闭包

6.1、闭包作用:

闭包可以保存函数内的变量,不会随着函数调用完而销毁

6.2、闭包的定义

在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数成为闭包。

6.3、构成闭包的条件

1、在函数嵌套

2、内部函数使用了外部函数的变量

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

6.4、闭包的使用

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("你好")
jerry("我在呢")

6.5、修改闭包

修改闭包内使用的外部变量使用nonlocal关键字完成

def func_out(num1):
    def func_inner(num2):
        nonlocal num1
        num1 = num2 + 10

    print(num1)
    func_inner(10)
    print(num1)

    return func_inner

f=func_out(10)
f(10)

7、装饰器

7.1、装饰器的作用

在不改变原有函数的源代码的情况下,给函数增加新的功能

装饰器符合了开发中的封闭原则

本质上相当于是一个闭包

装饰器的语法格式

def check(fn):
    def inner():
        print("登录验证。。。。")
        fn()
    return inner
#解释器遇到@check 会立即执行comment = check(comment)
@check
def comment():
    print("发表评论")

#comment = check(comment)
comment()

7.2、装饰器的使用

使用场景:函数执行时间统计

import time
def get_time(fn):
    def inner():
        start = time.time()
        fn()
        end = time.time()
        print("时间:",end-start)
    return inner

@get_time
def func():
    for i in range(10000):
        print(i)

func()

装饰器作用:在不改变已有函数源代码及调用方式的前提下,对已有函数进行功能的扩展

7.3、通用装饰器——带有参数的函数

def logging(fn):
    def inner(a,b):
        fn(a,b)
    return inner

@logging
def sum_num(a,b):
    result = a + b
    print(result)

sum_num(1,2)

7.4、装饰带有返回值的函数

def logging(fn):
    def inner(a,b):
        result=fn(a,b)
        return result
    return inner

@logging
def sum_num(a,b):
    result = a + b
    return result
    
result = sum_num(1,2)
print(result)

7.5、装饰带有不定长参数的函数

def logging(fn):
    def inner(*args, **kwargs):
        fn(*args, **kwargs )

    return inner

@logging
def sum_num(*args, **kwargs):
    print(args,kwargs)

sum_num(1, 2,3,age=18)

7.6、多个装饰器

def check1(fn1):
    def inner1():
        print("登录验证")
        fn1()
    return inner1
def check2(fn2):
    def inner2():
        print("登录验证2")
        fn2()
    return inner2
@check2
@check1
def comment():
    print("发表评论")

comment()

离函数最近的装饰器先装饰,然后外面的装饰器再装饰,由内到外的装饰过程

7.7、带有参数的装饰器

使用装饰器装饰函数的时候可以传入指定参数

语法:@装饰器(参数。。。。)

def logging(flag):

    def decorator(fn):
        def inner(num1,num2):
            if flag == "+":
                print("正在努力加法计算")
            elif flag == "-":
                print("正在努力减法计算")
            result = fn(num1,num2)
            return result
        return inner
    return decorator

@logging('+')
def add(a,b):
    result = a+b
    return result

result = add(1,3)
print(result)

带参数的装饰器

1、装饰器的外部函数只接受一个参数—被装饰的函数

2、需要给装饰器传参数需要在装饰器外部再增加一个函数

7.8、类装饰器

__ call __ 方法的使用

一个类里面一旦实现了 __ call __ 方法

那么这个类创建的对象就是一个可调用对象,可以像调用函数一样进行调用

class Check(object):
    def __init__(self,fn):
        self._fn = fn

    def __call__(self, *args, **kwargs):
        print("我是call方法")
        self._fn()

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

comment()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包装饰器是一种特殊的装饰器,它使用闭包的概念来实现。闭包是指一个函数可以访问并操作其外部函数中定义的变量。在Python中,闭包装饰器可以用于给函数添加额外的功能,同时保持函数的原始定义不变。 引用中的示例展示了装饰器传参的形式。在这个例子中,outer函数是一个装饰器,它将inner函数作为子函数返回,并在inner函数中添加了额外的功能。通过使用@outer装饰器语法,我们可以在add函数上应用outer装饰器,从而在调用add函数时执行装饰器中的代码。 引用中的示例展示了多层装饰器的使用。在这个例子中,outer1和outer2函数分别是两个装饰器,他们都返回一个inner函数。通过使用@outer1和@outer2装饰器语法,我们可以在outers函数上应用这两个装饰器,并在调用outers函数时按照装饰器的定义顺序执行相关的代码。 引用提供了关于Python闭包装饰器的使用方法的总结。这篇文章通过示例代码详细介绍了闭包装饰器的使用,对于学习和工作有一定的参考价值。 引用中的示例展示了装饰器的形式。在这个例子中,outer函数是一个装饰器,它将inner函数作为子函数返回,并在inner函数中添加了额外的功能。通过使用@outer装饰器语法,我们可以在add函数上应用outer装饰器,从而在调用add函数时执行装饰器中的代码。 综上所述,Python闭包装饰器是一种利用闭包概念实现的特殊装饰器,可以用于给函数添加额外的功能。这种装饰器可以通过装饰器传参的形式、多层装饰器的形式或普通的装饰器形式来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值