Python全栈最全学习之路-pyhton基础(九)

生成器装饰器和异常

一、 生成器

思考一:上节课协议中介绍了迭代器协议,但是需要定义类,那么只用函数可以生成吗?
  • 生成器
def fibonacci(end):
	n,a,b = 0,0,1
	while n < end:
		a,b = b,a + b
		yield b
		n += 1

在这里插入图片描述
利用yield可以将一个函数变成一个迭代器
yield具有和return一样的功能,可以返回值,同时也会暂停函数的执行,知道下一次next执行,才会继续往下运行

nab执行
001a,b=b,a+b;yield b
011n+=1;n<end;a,b=b,a+b;yield b
112n+=1;n<end;a,b=b,a+b;yield b
223n+=1;n<end;a,b=b,a+b;yield b

yield会停下来,直到下一次next调用
二、装饰器

思考一:刚才一个小小的改动就让函数变得不一样了,但终究改变了函数,能不能不改变函数,给一个函数增加功能呢?
思考二:比如别人调用了我定义的函数,但是我想知道别人传入了什么参数该怎么办呢?
  • 装饰器
def variables(func):
	def f(*args,**kwargs):
		print(args,kwargs)
		values = func(*args,**kwargs)
		return values
	return f
@variables
def f1(end):
	return end + 1

对于函数f1,不需要做任何改变,但是每次在调用的时候,都能看到传入的变量值具体是多少

  • 装饰器本质
    在这里插入图片描述
    装饰器本质也是利用了闭包将f1传入variables然后把f1重新引用为variables的返回值
  • 内置装饰器
class Person:
	def __init__(self,name,age,sex = '男'):
		self.name = name
		self.age = age 
		self.sex = sex
	@property # 调用方法可以像调用属性一样
	def play(self):
		print('%s 正在玩游戏,啊哈哈---' % self.name)
	@classmethod # 第一个参数自动传入类
	def learn(cls):
		print('%s 需要学习,emm---' % cls)
	@staticmethod # 不再自动传入self或cls
	def sleep():
		print('人都要睡觉')

property、classmethod、staticmethod是pyhton内置的三个装饰器,在项目中会使用到

  • 总结

1、装饰器
掌握:装饰器即闭包,只是传入的是一个函数
2、内置装饰器
掌握:三个内置装饰器的使用和效果

三、异常

	思考一:前面的学习过程中,始终小心翼翼,尽可能避免程序出现报错,但是程序始终是由可能报错的,那该怎么办呢?
	思考二:比如打开一个只读文件,这个文件可能还没有获取到,那么打开的时候就会报错,那么应该怎么办呢?
  • 异常
try:
	f = open('test.txt')
except:
	print('文件不存在')

在这里插入图片描述
当文件不存在时,程序不会报错,这样报错就不会导致程序结束

  • 异常的使用

语法规则:

try:
	pass
except Exception:
	raise Exception
else:
	pass
finally:
	pass

使用规则:

try:
	可能出现异常的代码
except Exception:
	抛出或者返回异常
else:
	没有报错执行
finally:
	以上执行完执行

注意事项:

try后面必须跟上except
except只有在函数中才能使用return
finally不管是否发生异常,始终都会执行
raise可以主动抛出异常
  • 断言使用

在这里插入图片描述
assert是断言,和if判断类似,只是判断为False的时候会报错

  • 总结

1、异常
掌握:异常就是报错
2、异常处理
掌握:异常处理的基本语法规则
3、断言
掌握:断言的使用
四、错误查找

思考一:错误和bug是不可避免的,那么如何快速查找和定位到错误是非常关键的,那么在Python中如何去查找错误呢?
  • 错误查找

在这里插入图片描述
在今后解决问题的过程中,应当自己找到错误代码行,报错原因及报错行,然后再去查找问题。
在自己无法解决需要寻求帮助时,也要掌握如何描述问题,把问题描述清楚的能力,掌握如何提问的技巧,这会大大节省双方的时间和精力
五、本节课总结
1、生成器
掌握:yield的使用
2、装饰器
掌握:装饰器的定义和使用
3、异常
掌握:异常的使用
4、错误查找
掌握:错误查找的方法
六、上节课作业
1、测试列表推导和不用列表推导那一种速度更快

import time
class RunTime:
    def __enter__(self):
        self.start_time = time.time()
        return self.start_time
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end_time = time.time()
        self.run_time = self.end_time - self.start_time
        print('Time consuming %s' % self.run_time)
with RunTime():
    li = []
    for i in range(10000000):
        li.append(i)
with RunTime():
    li = [i for i in range(10000000)]

在这里插入图片描述
2、range不可以使用小数做步长,实现一个可迭代对象,可以实现小数步长

class Float_range:
    def __init__(self,start,end = None,step = 1):
        if not isinstance(start,(int,float)):
            raise TypeError
        elif end != None and not isinstance(end,(int,float)):
            raise TypeError
        elif not isinstance(end,(int,float)):
            raise TypeError
        elif end and end < start:
            print('开始值不能小于结束值')
        elif step < 0:
            print('步长不能小于0')
        else:
            if end == None:
                self.start = 0
                self.end = start
                self.step = step
            else:
                self.start = start
                self.end = end
                self.step = step
    def __iter__(self):
        return self
    def __next__(self):
        import decimal
        res = self.start
        if float(self.start) < float(self.end):
            self.start = decimal.Decimal(str(self.start)) + decimal.Decimal(str(self.step))
            return res
        else:
            raise StopIteration

在这里插入图片描述
七、作业
1、利用装饰器,记录函数的运行次数
2、打开一个只读文件,如果文件不存在,则去创建这个文件

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值