Python基础之零碎知识——闭包、装饰器、推导式、迭代器、递归函数、异常处理机制

Python基础之零碎知识——闭包、装饰器、推导式、迭代器、递归函数、异常处理机制

该部分作为python里的一些零碎的知识,但是又极为重要。掌握这些知识点,我相信大家的python水平定能提升一个台阶。

一、闭包

1. 闭包条件:
	a. 外部函数中定义了内部函数
	b. 外部函数是有返回值的
	c. 返回值是:内部函数名
	d. 内部函数引用了外部函数的变量
2.格式:
def 外部函数()
	def 内部函数()
	Return 内部函数
3.闭包的作用:
a. 可以使用同级的作用域
b. 读取其他元素的内部变量
c. 延长作用域
4.闭包的缺点:
a. 作用域没有那么直观
b. 因为变量不会被垃圾回收所以有一定的内存占用问题
5.闭包的总结:
a. 闭包优化了变量,原来需要类对象完成的工作,闭包也可以完成	
b. 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
c.闭包的好处,使得代码变得简洁,便于阅读代码
d.闭包是理解装饰器的基础
# input
def outer():
    name = 'hello word!!!'
    def inner():
        print(name)
    return inner

a = outer()  # a = outer() = inner
a() # a() = inner()

#output
hello word!!!

二、装饰器

以@开头,装饰器是在函数调用之上的修饰器,在不改变项目原有代码的基础上,增加一些额外的功能

1.特点:
a. 函数A是作为参数出现的(函数B就接收函数A作为函数)
b. 要有闭包的特点
2.调用
@装饰器函数   #使用装饰器
3.多个装饰器
当存在多个装饰器的时候,哪个距离装饰函数近,先运行哪个装饰器。
#input
# 装饰器带参数
"""
带参数的装饰器是三层的
最外层的参数负责接收装饰器参数
里面的内容还是原装饰器的内容

"""
import time
def outer(a):   # 第一层:负责接收装饰器的参数
    def decorate(func): # 第二层:负责接收函数的
        def wrapper(*args,**kwargs):    # 第三层:负责接收函数的参数
            func(*args)
            print('------->铺地砖{}块'.format(a))

        return  wrapper
    return decorate

@outer(10)
def house():
    b = input('请输入时间:')
    print('我{}日期拿到的房子的钥匙,是毛坯房......'.format(b))


house()

#output
请输入时间:10.2010.20日期拿到的房子的钥匙,是毛坯房......
------->铺地砖10
4.装饰器开发项目——登陆、付款验证
#input
# 开发:验证登录

import time

islogin = False

# 定义一个登陆函数
def login():
    username = input('请输入用户名:')
    password = input('输入密码:')
    if username == 'admin' and password == '123456':
        return True
    else:
        return False



# 定义一个装饰器,进行付款验证
def login_required(func):
    def wrapper(*args,**kwargs):
        global islogin
        print('------------付款中---------')

        if islogin:
            func(*args,**kwargs)
        else:
            print('用户没有登陆,不能付款')
            islogin = login()
            print('result',islogin)
    return wrapper

@login_required
def pay (money):
    print('正在付款,付款进而使:{}元'.format(money))
    print('付款中.....')
    time.sleep(2)
    print('付款完成!')


pay(1000)
pay(500)

#output
------------付款中---------
用户没有登陆,不能付款
请输入用户名:admin
输入密码:123456
result True
------------付款中---------
正在付款,付款进而使:500元
付款中.....
付款完成!

三、推导式(生成器)

1. 生成器定义方式一:

推导式主要有三种:列表推导式、字典推导式、集合推导式。三者的语法结构基本一样,只有使用的括号有区别。

如:列表推导式我们又可以理解为循环创建列表。
等效于使用for循环给列表添加数据

语法格式:

列表推导式:
格式:[表达式 for 变量 in 旧列表]
 或者 [表达式 for 变量 in 旧列表 if 条件]

字典、集合推导式将列表推导式中的 [ ] 换成 {} 即可。

但由于字典的特殊性,我们在定义变量和表达式时
均需要以键值对的形式创建。
#input
# for 循环
list_a = list()
for a in range(5):
    list_a.append(a)
print('list_a=',list_a)

# 列表推导式

# 列表推导式的嵌套,添加多个并行筛选条件
list_b = [[x for x in range(0, b)] for b in range(22) if b % 2 == 0 and b != 0]
print('list_b=',list_b)

#字典推导式
# 因为key是唯一的,所以最后value都是1
dict_a = {key: value for key in 'python' for value in range(2)}
print(dict_a)

# 可以根据键来构造值
dict_b = {key: key * key for key in range(6)}
print(dict_b)

# 遍历一个有键值关系的可迭代对象
list_phone = [('HUAWEI', '华为'), ('MI', '小米'), ('OPPO', 'OPPO'), ('VIVO', 'VIVO')]
dict_c = {key: value for key, value in list_phone}
print(dict_c)


#集合推导式
# 遍历一个可迭代对象生成集合
set_a = {value for value in '有人云淡风轻,有人负重前行'}
print(set_a)

#部分例子取自:CSDND大佬——Python碎片

#output
list_a= [0, 1, 2, 3, 4]
list_b= [[0, 1], [0, 1, 2, 3], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
dict_a= {'p': 1, 'y': 1, 't': 1, 'h': 1, 'o': 1, 'n': 1}
dict_b= {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
dict_c= {'HUAWEI': '华为', 'MI': '小米', 'OPPO': 'OPPO', 'VIVO': 'VIVO'}
set_a= {'风', '行', ',', '负', '淡', '人', '前', '有', '云', '重', '轻'}

2.生成器定义方式二:

通过函数来定义生成器

只要函数中出现了yield关键字,
说明函数就不是 函数啦,变成生成器了

def func()
		n = 0
		while True:
			n +=1
			yield n

注意:在迭代器中取值和传值有特殊的规则

__next__()  获取下一个元素

Send(value) 向每次生成器调用中传值,
注意:第一次调用send(None)

四、迭代器

通过列表生成器(列表推导式),我们可以直接创建一个列表,但是受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间。如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量的空间。在python中,这种一边循环一边计算的机制,称为迭代器:generator

1.可迭代对象

说到迭代器,可迭代对象是避不开的话题。
可迭代对象有哪些呢?

可迭代对象:生成器 元组 列表 集合 字典 字符串
判断一个对象是否可迭代:isinstance(list,iterable)
2.迭代器的特点

迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,
知道所有的元素被访问完结束,
迭代器只能往前不会后退。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

3.使用iter() 函数 创建迭代器

iter(iterable)#一个参数,要求参数为可迭代的类型

4.迭代器和生成器的关系
生成器与迭代器关系:迭代器包含生成器
#input
def task1(n):
    for i in range(n):
        print('正在搬第{}块砖'.format(i))
        yield None

def task2(n):
    for i in range(n):
        print('正在听第{}首歌'.format(i))
        yield None

g1 = task1(10)
g2 = task2(5)

while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        break

#output
正在搬第0块砖
正在听第0首歌
正在搬第1块砖
正在听第1首歌
正在搬第2块砖
正在听第2首歌
正在搬第3块砖
正在听第3首歌
正在搬第4块砖
正在听第4首歌
正在搬第5块砖

五、递归函数

递归函数是普通函数的一种表现形式
特点:在函数中再次调用函数自身

优点:

递归使代码看起来更加整洁、优雅
可以用递归将复杂任务分解成更简单的子问题
使用递归比使用一些嵌套迭代更容易

缺点:

递归的逻辑很难调试、跟进
递归调用的代价高昂(效率低),因为占用了大量的内存和时间。

六、异常处理机制

在我们运行python代码时,免不了出现各种各样的错误。当程序出现错误,但是我们又不想程序停止运行,且想知道是不是某种确定原因报错时,我们就会用到异常处理机制了。

格式:
第一种:
Try:
可能出现异常的代码
Except 错误类型:
如果有异常,执行的代码
Except exception as err:
未区分的所有异常,执行代码
[Finally:
无论是否存在异常都会被执行的代码]

第二种:
Try:
有可能有异常的代码
Except 类型1:
Pass
Else:
如果try中没有发生异常则进入的代码

注意:如果使用else则try代码中不能出现return

抛出异常的格式:

raise exception异常类型(‘自己编辑报错内容’)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值