3. 装饰器
3.1 介绍
拓展原来函数功能的函数
返回函数的函数
-
在不用更改原来函数的代码的前提下给函数增加新功能
def hello(): print("hello") def add(): print("begin........") hello() print("end..........") add() Result: begin........ hello end.......... ######################### def add(func): def result(): print("begin........") func() print("end..........") # return return result @add # 定义一个装饰器,传入hello()函数到add(func)函数并作 def hello(): # 为参数func,在add()函数中定义一个函数并返回,调用 print("hello") # hello()函数得到的即为返回函数 # return hello() Result: begin........ hello end..........
3.2 带参数的装饰器
# 带参数的装饰器就是多一层函数
def add_hello_1(name=None): # 主要用于传参数
def add_hello_2(func): # 主要用于传函数
def result(*args,**kwargs): # 主要用于对函数的功能增加和魔法参数的传入
print("{}.begin........".format(name))
print(args) # args为Tuple
print(kwargs) # kwargs为Dictionary
res=func(*args,**kwargs)
print("{}.end..........".format(name))
return res
return result
return add_hello_2
@add_hello_1("calculate") # 第一层函数的参数
def add(a,b,*args,**kwargs):
print(a+b)
print(a)
print(b)
print(args)
print(kwargs)
return a+b
add(4,5,k1=1,k2=2) # add()函数4,5都储存到a,b中,Tuple中无数据;result()中4,5
# 储存到Tuple中
Result:
calculate.begin........
(4, 5)
{'k1': 1, 'k2': 2}
9
4
5
()
{'k1': 1, 'k2': 2}
calculate.end..........
9
3.3 wraps
- 最内层函数之前加
@wraps(func)
def printInfo(func):
print("###########################")
print("name:{}".format(func.__name__))
print("doc:{}".format(func.__doc__))
print("###########################")
# 带参数的装饰器就是多一层函数
def add_hello_1(name=None): # 主要用于传参数
def add_hello_2(func): # 主要用于传函数
def result(*args,**kwargs): # 主要用于对函数的功能增加和魔法参数的传入
"""result()函数"""
print("{}.begin........".format(name))
print(args) # args为Tuple
print(kwargs) # kwargs为Dictionary
res=func(*args,**kwargs)
print("{}.end..........".format(name))
printInfo(func)
return res
return result
#################从这里开始add()函数的名称变为result()函数名,文档变为 result()文档
return add_hello_2
@add_hello_1("calculate") # 第一层函数的参数
def add(a,b,*args,**kwargs):
"""add()函数"""
print(a+b)
print(a)
print(b)
print(args)
print(kwargs)
return a+b
add(4,5,k=0)
Result:
calculate.begin........
(4, 5)
{'k': 0}
9
4
5
()
{'k': 0}
calculate.end..........
###########################
name:add
doc:add()函数
###########################
9
##########################################################################
# 解决方法:
from functools import wraps
最内层函数之前加@wraps(func)
3.4 类的装饰器
-
为类进行扩充
def introduce(cls): cls.hello=lambda self:print("hello......") return cls @introduce class People: pass people=People() people.hello() --> hello......
4. 迭代器
4.1 介绍
- 迭代意味着重复多次,就想循环那样
- 实现了方法
__iter__
的对象是可迭代的,而实现了方法__next__
的对象是迭代器 - 调用方法
__next__
时(或next()
),迭代器返回下一个值 - 如果迭代器没有可供返回的值,触发
StopIteration
异常
4.2 实例
# 用List实现迭代器
list=[1,2,3,4]
l=iter(list)
type(l) --> <class 'list_iterator'>
next(l) --> 1
l.__next__() --> 2
next(l) --> 3
l.__next__() --> 4
next(l) --> StopIteration
###############################
# 自定义迭代器
class iteration:
value=0
def __iter__(self):
return self
def __next__(self):
self.value+=1
if self.value>10:
raise StopIteration
return self.value*self.value
iteration=iteration()
for i in iteration:
print(i)
Result:
1
4
9
16
25
36
49
64
81
100
5. 生成器
5.1 介绍
- 生成器是一种使用普通函数语法定义的迭代器
- 包含yield语句的函数都被称为生成器
- 不是用return返回一个值,而是可以生成多个值,每次一个
- 每次使用yield生成一个值后,函数都将冻结,即在此停止执行
- 被唤醒后,函数将从停止的地方开始继续执行
5.2 实例
def create():
for i in range(1,11):
yield i
a=create()
a.__next__() --> 1
next(1) --> 2
4. 异常处理
4.1 异常介绍
异常是一个类
异常不被捕获就会终止程序
-
内置异常类
类名 描述 Exception 几乎所有异常类都是它派生 AttributeError 引用属性或给它赋值失败是引起 OSError 操作系统不能执行指定的任务时引起,有多个子类 IndexError 使用序列中不存在的索引时引起,为LookuoError的子类 KeyError 使用映射中不存在的键时引起,为LookuoError的子类 NameError 找不到名称(变量)时引起 SyntaxError 代码不正确时引发 TypeError 将内置操作或函数用于类型不正确的对象时引发 ValueError 将内置操作或函数用于这样的对象时引发:其类型正确但包含的值不合适 ZeroDivisionError 在除法或求模运算的第二个参数为0时引发
4.2 异常捕获
-
try.......except(....) as name....finally...
# 1 try: 5/0 except: print("wrong") Result: wrong # 2 try: 5/0 except(ZeroDivisionError,TypeError): print("wrong") Result: wrong # 3 try: 5/"s" except(ZeroDivisionError) as e: print(e) except(TypeError) as e: print(e) Result: unsupported operand type(s) for /: 'int' and 'str' # 4 try: file=open('hello.txt') read=file.read() except(FileNotFoundError) as e: print("wrong") print(e) finally: try: file.close() except: print("ok") Result: wrong [Errno 2] No such file or directory: 'hello.txt' ok
4.3 自定义异常
自定义异常继承自
Exception
-
触发利用
raise exception_name
class MyException(Exception): def __init__(self,err_code,err_msg): self.err_code=err_code self.err_msg=err_msg def __str__(self): return "MyException:{}---{}".format(self.err_code,self.msg) raise MyException(101,"myexception") Result: Traceback (most recent call last): File "D:/study/python/MyTest/test.py", line 8, in <module> raise MyException(101,"myexception") __main__.MyException: <exception str() failed> ######################################## try: raise MyException(101, "myexception") except(MyException) as e: print(e) Result: MyException:101---myexception
4.4 抛出异常和异常传递
- 如果在异常产生的地方不捕获,那么它会一层一层的往上传递