第五章 函数
5.1 三元运算
- 又称为三目运算
和运算符相关
val = v if v else 666
val = v or 666 # 源码中会见到
Note:为了赋值
# 简单条件赋值时使用
v = 前面 if 条件 else 后面
# 用户输入,如果是整数,则转换,否则赋值为None
data = input('>>>')
value = int(data) if data.isdecimal() else None
5.2 函数基础
面向过程【可读性差、可重用性差】—> 函数式编程—>面向对象
# 如果给其他人发送邮件,可以把发送程序进行封装起来,可缩减代码长度和提高重复利用性。
函数式编程
- 将n行代码放在别处,并取别名,以后可以调用
- 场景:
- 代码重复执行
- 代码量特别多,超过一屏,可以选择函数编程(一般控制在一屏以内)
1. 定义函数
可以定义一个由自己想要功能的函数,以下是简单的规则:(5)
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def functionname( parameters ):
"函数_文档字符串"
function_suite # 函数体
return [expression]
# 默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
# 函数定义
# way1
def 函数名():
# 函数体
pass
# 函数的执行
函数名() # 会自动执行
# way2
# 形参可以是多个
def 函数名(形参):
# 函数体
pass
函数名(实参)
Note1(1)
- None方法类似函数,但不是(方法操作是s.upper(),方式,而函数是直接调用,len(),open())
2. 两种参数(示例)
形参(形式参数)与实参(实际参数)的位置关系。
def 函数名(形参):
# 函数体
pass
函数名(实参)
# 无形参示例
def get_sum_list()
sum = 0
for i in li:
sum += i
print(get_sum_list())
# 有形参示例
# 请写一个函数,函数计算列表 info = [11,22,33,44,55] 中所有元素的和。
info = [11, 22, 33, 44]
def get_list_sum(li):
sum = 0
for i in li:
sum += i
print(sum)
get_list_sum(info)
3. 函数的返回值
Note2(4)
- return [表达式] 结束函数,选择性地返回一个值给调用方(func()为返回值)。
- return 1, 2 ,3 会返回tuple:(1, 2, 3)
- 函数默认返回值是 None ,有时可以使用其作为flag
- 可变类型(list)的基本上都是None, 不可变(str)基本上会返回新值
def func(arg):
return 9 # 返回值为9,默认为None,可以返回任何类型的数据
val = def func(v)
# 示例2
# 让用户输入一段字符串,计算字符串中有多少A,就在文件中写入多少‘echo’
def get_char_count(arg):
count = 0
for i in arg:
count += 1
def write_file(data):
open('a.txt', mode='w', encoding='utf-8') as v:
if len(data) == 0:或者 if not bool(data):
return '写入失败'
v.write(data)
return '写入成功'
print(count)
content = input()
4. 函数的四种方式
# way1 无形参,无return
def fun1():
pass
fun()
# way2 有形参,无return
def fun2(arg):
pass
fun2(v)
# way3 无形参,有return(指定值)
def fun3():
pass
return 9
val = fun3(v)
# way4 有形参,有return(变量)
def fun4(arg1, arg2):
pass
return arg1 + arg2
val = fun4(v1 + v2)
5. 练习(3)
# 1. 写函数,计算一个list中有多少个数字,打印,有%s个数字
# 判断数字:type(a) == int
# 2. 写函数,计算一个列表中偶数索引位置的数据构造成另外一个列表,并返回。
# 3. 读取文件,将文件的内容构造成指定格式的数据,并返回。
a.log文件
alex|123|18
eric|uiuf|19
...
目标结构:
a. ["alex|123|18","eric|uiuf|19"] 并返回。
b. [['alex','123','18'],['eric','uiuf','19']]
c. [
{'name':'alex','pwd':'123','age':'18'},
{'name':'eric','pwd':'uiuf','age':'19'},
]
5.3 变量作用域&嵌套
1. 函数传参方式(2+1)
-
参数传递方式分为位置传参、关键字传参、函数作为参数进行传递。
-
位置传参
- 严格按照位置进行传参
# 示例
def func(a1, a2):
pass
func(1, 3)
func(1, [1, 2, 3])
- 关键字传参
# 示例
def func(a1, a2):
pass
func(a1 = 1, a2 = [1, 2, 3])
func(a1 = 1, 2 ) # 此时会报顺序错误
Note3(1)
- 关键字传参可以和位置传参混合使用,但 位置参数 必须在 关键字传参前。
2. 函数定义参数(3)
- 函数定义中,def func() 括号中可以省略、默认参数和 *args/**kwargs。
1. 省略参数
# 示例
def func():
pass
2. 默认参数
- 注意默认参数一定要在位置参数之后
- 在定义默认参数时,慎用可变类型变量
# 示例
def func(a1, a2=2):
pass
# 调用方法,有默认参数时,可以不用省略,采取默认值,也可以重新赋值
func(1)
func(1, 3)
# 默认形参时,如果默认是可变类型的需要谨慎使用
# 如果想要给values设置默认是空list
def func(data, value=[]):
pass
# 推荐
def func(data, value=None):
if not value:
valu=[]
3. *args/**kwargs(万能参数)
- *args 表示接收所有由实参通过位置传参方式,传递过来的数据,可以和位置参数一起使用。
- 接收到的参数值,会通过循环加入tuple中
# 示例 : 可以传递任意类型数据
def func(*args):
pass
# [1, 2, 3]会被当成整体变成tuple中的一个元素
func(1, 2, 3, [1, 2 ,3])
# 直接赋值, [1, 2, 3]也会循环取出追加到tuple中
func(4, 5 ,6 ,*[1, 2 ,3])
- **kwargs 表示接收所有关键字传参的数据,也可以通过**{'k1': 1, 'k2':2},循环取出keys对,加入形参dict中
# 示例 :只能通过关键字传参,或者dict赋值
def func(**kwargs):
print(kwargs)
# [1, 2, 3]会被当成整体变成dict中 'd': [1, 2, 3]
func(a=1, b=2, c=3, d=[1, 2 ,3])
# 直接赋值, {'k1': 4, 'k2': 5}也会循环取出追加到形参的dict中
func(a=1, b=2, c=3, d=[1, 2, 3], **{'k1': 4, 'k2': 5})
Note4(4)
- 形参中的默认参数,也可以使用位置传参方式
- 传参时,有*(**)时,会直接赋值 (循环加入) 给形参
- 不带* / **的实参,会转换为tuple / dict
- 传入的数据都是循环加入tuple / dict中
3. 作用域&函数嵌套
- 变量作用域时是变量的有效作用范围,在python中函数就是一个局部作用域。由于作用域的不同,变量的有效范围也不同,根据作用范围可以把变量分为,全局变量和局部变量。
- 全局变量:可供任何函数进行使用,修改,在python文件第一层的变量。在python中一般把全局变量命名为全部大写(规范),例如:USRE_NAME = 'henry'。
- 局部变量:可以把函数中的变量视为局部变量。函数体中变量为函数所私有(只能被其子函数进行使用)。
# 示例1
a = 'henry'
def func():
print(a)
a = 123
func() # 此时使用的是全局变量, 结果是 123
# 示例2
a = 'henry'
def func1():
def func2():
a = 'echo'
print(a)
func2()
print(a)
a = 123
func1()
print(a)
# echo 123 123
Note5(4)
- python文件就是一个全局作用域
- 函数是一个 (局部) 作用域
- 局部作用域中的数据归自己私有
- 作用域中查找数据规则
- 优先查找自己作用域,自己没有,去父籍作用域查找直到找到全局作用域
- 查找不到会报错,默认只能使用父籍作用域中的变量值不能赋值(可变类型可以修改)
# 示例
# 对于可变变量可以进行修改
a = [1, 3, 5, 7]
def fun1():
a.append('henry')
fun1()
print(a) # 此时a会被修改
# 两种赋值的方法
# 可以使用 global 关键字对全局变量进行重新赋值
global name
name = 'alex' # 给全局变量重新赋值
# 可以使用 nolocal 关键字对父籍变量进行重新赋值, 在父籍找不到时,会报错
nonlocal name
name = 'alex' # 给父籍变量重新赋值
Note6(3)
- 对于可变变量可以进行修改
- global 关键字对全局变量进行重新赋值
- nolocal 关键字对父籍变量进行重新赋值, 在父籍找不到会报错
5.4 函数进阶
- 高阶函数(3)
- 对函数赋值
- 函数当作参数传递
- 把函数当作返回值
# <class 'function'>
def func ():
pass
print(type(func))
# 函数可以认为是一变量
1. 函数赋值
def func():
print(123)
v = fun # 指向相同的地址
v()
# 示例
def func():
print(123)
v1 = [func, func, func]
v2 = [func(), func(), func()]
print(v1)
print(v2)
2. 函数传参
def func(arg):
print(arg)
def show():
return 999
func(show) # 999 None
3. 函数作为返回值
def func():
print(1,2,3)
def bar():
return func
v = bar() # func
v()
Note7(3)
- 注意func 和 func() 的区别
- 函数(实际是内存地址)可以放入set()中(不常用), 或dict中(一般用于values,也可以放在key中但不常用)
- 函数一旦定义,只要进行加载,就是不可变,可 hash
# 10 个函数, 一般是建立字典
def func():
print('话费查询')
def bar():
print('***')
def base():
print('***')
info = {
'f1': func,
'f2': bar,
'f3': base
}
choice = input('please input your choice: ')
name = info.get('choice')
if not name:
print('输入不存在')
else:
name()
3. lambda表达式
# 三目运算,为了解决简单的if...esle的情况
# lambda,为了解决简单函数的情况
eg:
def func(a1, a2):
return a1 + a2
# 可以改写为,a1 + 100 即为return 值
func = lambda a1, a2: a1 + 100
# way1 直接使用
func = lambda : 100
func = lambda a: a*10
func = lambda *args, **kwargs: len(args) + len(kwargs)
# way2 使用全局变量
DATA = 100
func = lambda a: a + DATA
func(1)
# way3 使用父籍变量
DATA = 100
def func():
DATA = 1000
func1 = lambda a: a + DATA
v = func1(1)
print(v)
func()
# way4 使用条件判断 ########
func = lambda n1, n2: n1 if n1 > n2 else n2
# 练习1
USER_LIST = []
func1 = lambda x: USER_LIST.append(x)
v1 = func1('alex')
print(v1) # None
print(USER_LIST) # ['alex']
# 练习2
func1 = lambda x: x.strip()
v1 = func1(' alex')
print(v1) # 'alex'
# 练习3
func_list = [lambda x: x.strip(), lambda y: y+100, lambda x,y: x+y]
v1 = func_list[0](' alex')
print(v1) # 'alex'
Note8(2)
- 用于表示简单函数(一行解决的函数)。
- lambda 表达式会默认返回冒号:之后的值
4. 内置函数(30)
-
自定义函数
-
内置函数(31)
- 强制转换(7):int(),str, bool, list,dict,tuple,set
- 输入输出(2):print, input
- 其他(5):type, id, range, open, len
- 数学(7)
- abs,round,float(int(55.5)保留整数部分)
- max,min,sum,
- divmod(两数相除,得商和余数, 两个值)
- 面向对象相关(4):dir,super,issubclass,isinstance
# divmod. 练习
USER_LIST = []
for i in range(1, 836):
tem = {name':'hello-%s' % i, 'email':'XXXX%s@qq.com' %s}
USER_LIST.append(tem)
"""
要求:
每页展示10条
根据用户输入的页码,查看
"""
-
进制转换(3):bin(0b,int<—>bin),oct(0o,int<—>oct),int(其他进制转int),hex(0x,int<—>hex)
# base 默认为 10 v1 = '0b1101' result = int(v1, base = 2) # 转8进制 v1 = '0o1101' result = int(v1, base = 8) # 转16进制 v1 = '0x1101' result = int(v1, base = 16)
# ip 点分二进制,将十进制转为二进制并通过 . 连接ip = '192.168.12.79' ip = '192.168.12.79' li = ip.split('.') l = [] for i in li: i = int(i) i = bin(i) i = str(i).replace('0b', '') i = i.rjust(8, '0') l.append(i) s = '.'.join(l) print(s)
-
编码相关
-
chr() :把int型数据,转换为unicode编码
- ord():把unicode转换为字符
# 生成验证码 import random # 导入一个模块 def get_random_data(length=6): data = [] for i in range(length): v = random.randint(65,90) # 得到一个随机数 data.append(v) return ' '.join(data) code = get_random_data()
print(code)
8. map / filter / reduce(py2)/zip
- **map**,循环每个元素(第二个参数),然后让元素执行函数(第一个参数),将每个函数结果保存到新的list中,并返回。(批量修改数据)
```python
# map操作的 func 是一个函数 v 必须是可迭代,
v = [11, 22, 33]
def func(arg):
return arg + 100
result = map(func, v) # 将函数的返回值添加到空list中[111, 122, 133]
print(list(result))
# 使用lambda 改写
result = map(lambda x: x+100, v)
print(result) # py2直接返回
print(list(resutl)) # py3会返回一个object,可用list()查看
- filter
```python
# 结果为True的时候,才返回数据
v = [1, 2, 3, 'welcome', 4, 'hello']
result = filter(lambda x: type(x) == int, v) # 生成新list
print(list(result))
```
- reduce
import functools
v = [1, 2, 3, 4]
result = functools.reduce(lambda x,y: x*y, v)
print(result)
- zip
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
zip(a,c)
# 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
zip(*zipped)
# 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
5.5 函数闭包
1. 函数闭包
def func(name):
def inner():
print(name)
return inner
v1 = func('henry')
v1()
v2 = func('echo')
v2()
# 不是闭包
def func(name):
def inner():
return 123
return inner
# 闭包:封装值 + 内层函数需要使用
def func(name):
def inner():
print(name)
return 123
return inner
Note9(5)
- 闭包,为函数创建一块区域(内部变量供自己使用),为以后执行提供数据;
- 闭包是能够读取其他函数内部变量的函数。
- 执行完毕+内部数据不被其他程序使用会被销毁
- 应用:装饰器,SQLAlchemy源码
- 由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)
2. 递归(效率较低)
- 递归限制为1000次
def func(i):
print(i)
func(i+1)
# 斐波那契数列
def func(a, b):
print(b)
func(a, a+b)
# 递归
def fun(a):
if a == 5:
return 100
result = func(a+1) + 10
return result
v = func(1)
# 注意
def fun(a):
if a == 5:
return 100
result = func(a+1) + 10
v = func(1)
5.6 装饰器和推导式
- 使用func.__name__获取被调用的func函数名,func为形参
1. 装饰器(重点)
def func():
def inner():
pass
return inner
v = func()
print(v) # inner 函数
# ##############################
def func(arg):
def inner():
print(arg)
return inner
v1 = func(1) # 1
v2 = func(2) # 2
# ##############################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
v = fucn(f1)
v() # 123
# ##############################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1)
result = v1()
# 执行inner函数 / f1含函数 -> 123 print(result)
# None
# ##############################
def func(arg):
def inner():
return arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1)
result = v1() # 123 666
- 装饰器示例
def func(arg):
def inner():
print('before')
v = arg()
print('after')
return v
return inner
def index():
print('123')
return 666
# 示例
v1 = index() # 123
v2 = func(index) # before 123 after
v3 = v2()
v4 = func(index) # before 123 after
index = v4
index()
index = func(index) # before 123 after
index()
# 第一步,执行func函数,并将下面的函数当作函数传递,相当于func(index)
# 第二部,将func返回值,重新赋值为下面的函数名,index = func(index)
def func(arg):
def inner():
return arg()
return inner
@func
def index():
print(123)
return 666
print(index) # <function func.<locals>.inner at 0x1054a16a8>
应用示例:
# 计算函数执行时间
def wrapper(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return func()
return inner
import time
@ warpper
def func():
time.sleep(2)
print(123)
@ warpper
def func():
time.sleep(1.5)
print(123)
# 判断用户是否登陆
Note10(2)
- 目的:在在不改变原函数的基础上,在执行函数前后自定义一些操作
- 场景:想要为函数扩展功能时
- 编写装饰器
# 装饰器的编写(示例)
def wrapper(func): # 必须有一个参数
def inner():
ret = func()
return ret
return inner
# 应用 index = wrapper(index)
@wapper
def index():
pass
@wapper
def manage():
pass
# 在执行函数,自动触发装饰器
v = index()
print(v)
# 导入本目录下的其他py文件
import a
a.f1()
a.f2()
a.f3()
- 编写格式
def wrapper(func):
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
为什么要加*args,**kwargs?
2. 关于参数
# 让参数统一的目的:为装饰的函数传参
def x(func):
def inner(a, b):
return func()
return inner
@x
def index():
pass
index(1, 2)
- 返回值
# 装饰器建议写法
def wrapper(function):
def inner(*args, **kwargs):
v = funtion(*args, **kwargs)
return v
return inner
@wrapper
def func():
pass
- 带参数的装饰器
# 第一步:v = wrapper(9)
# 第二步:ret = v(index)
# 第三步:index = ret
def x(counter):
def wrapper(function):
def inner(*args, **kwargs):
v = funtion(*args, **kwargs)
return v
return inner
return wrapper
@x(9)
def index():
pass
# 示例:
# 写一个带参数的装饰器,实现,参数是多少,被装饰器就要执行多少次,最终返回一个list
def x(*args):
def wrapper():
def inner():
li = [index() for i in range(args[0])]
return li
return inner
return wrapper
@x(9)
def index():
return 8
v = index()
print(v)
- 元数据
- 多个装饰器:@x1 @x2
3. 推导式
-
list推导式(生成式)
- 格式(生成一个list)
vals = [i for i in 'henry'] v = [i for i in 可迭代对象 if 条件] # 满足条件生成list v = [i if i > 5 else i+1 for i in 可迭代对象 if 条件] # 满足条件生成list
# 新浪 def num(): return [lambda x: x * i for i in range(4)] print([m(2) for m in num()])
-
set推导式
- 格式
# 满足条件生成set,会去重,条件判断可以省略 v = {i for i in 可迭代对象 if 条件}
-
dict推导式
- 格式
# 满足条件生成dict,但需要key值和冒号:,条件判断可以省略 v = { 'k' + str(i): i for i in 可迭代对象 if 条件}
5.7 迭代器&生成器
类:int ,str, list…. / bytes(b'xxx'), datetime
对象:由类创建的数据
类和对象
1. 迭代器(class:iterator)
-
展示list中所有数据
- 迭代器:对某种(str/list/tuple/dict/set) (序列)对象中的元素,进行逐个获取。
- 表象:具有__next__()方法,
-
list —> 迭代器:
- v = iter([1, 2, 3, 4])
- val = [1, 2, 3, 4].__iter__()
-
迭代器获取每一个元素:v.next
-
直到报错:StopIteration,表示迭代终止
v = [1, 2, 3, 4] val = iter(v) value = val.__next__() print(value)
-
甄别:数据中是否包含__next__()方法
- for循环的内部,首先把数据转化为iter,反复执行iter.__next__(),取完不报错
2. 可迭代对象
- 具有__iter__()方法,必须返回一个迭代器(生成器)
- for循环
3. 生成器(函数的变异)(class:generator)
- yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级
- send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换
- 生成器基础
def func():
pass
func()
# 生成器函数(内部是否包含yield)
def func(arg):
arg = arg + 1
yield 1
yield 2
yield 100
# 函数内部代码不执行,返回一个生成器
val = func(100)
# 生成器:可以被for循环的,一旦开始循环,函数内部代码就开始执行
for i in val:
print(i)
# 遇到第一个yield会把后面的值赋值给 i
# 如果 yield 已经执行完毕,则意味着for循环结束
# 边使用边执行
def func():
count = 1
while True:
yield count
count += 1
# v 只取yield值,是一个生成器对象
v = func()
for i in v:
print(i)
# 查看v中有哪些方法
dir(v)
Note11(4)
- 函数中如果存在yield,则该函数为生成器函数,调用生成器函数会返回一个生成器
- 只有被for循环时,生成器内部代码才会执行,每次循环都会获取yield的返回值
- 即使函数内部的yield函数永远执行不到,也是生成器
- 生成器也是一种特殊的迭代器,也是一个可迭代对象
class Foo(object):
def __iter__(self):
return iter([1, 2, 3])
yield 1
yield 2
obj = Foo(object)
- 生成器中send
Note12(2)
- send方法,会触发一次next操作,yiled结果为其返回值
- 总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。
- 需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错
def func():
print(123)
n = yield('aaa')
print('----->', n)
yield 'bbb'
data = func()
next(data)
v = data.send('太厉害了,直接传进去了')
print(v)
- 生成器示例
# 示例:读取文件
def func():
curse = 0
while True:
f = open('db','r','utf-8')
f.seek(curse)
data_list = []
for i in range(10):
line = f.readline()
if not line:
return
data_list.append(line)
curse = f.tell()
f.close
for row in data_list:
yield row
# redis 示例
import redis
coon = redis.Redis(host='192.168.12.12')
- yield from 关键字
# yield from (py3.3之后)
def base():
yield 88
yield 99
def bar():
return 123
def func():
yield 1
yield from base()
yield from bar() # 报错,int 不可迭代,如果可迭代,则循环取出
yield 2
yield
- 生成器推导式
v1 = [i for i in range(10)] # list推导式,立即产生数据
def func():
for i in range(10):
yield i
v2 = func() # 与下面v2相同
v2 = (i for i in range(10)) # 生成器推导式,不会立即产生数据
-
酸爽生成器
-
所有生成器取一次就没有了
-
不取不会执行,惰性运算
-
# 示例1
ret = filter(lambda n: n%3==0, range(10))
print(len(list(ret))) # 4
print(len(list(ret))) # 0
# 示例2
def add(n, i):
return n + i
def test():
for i in range(4):
yield i
g = test()
for n in [1, 10]:
g = (add(n, i) for i in g)
print(list(g))
# [20 21 22 23 24]
# 示例3
def add(n, i):
return n + i
def test():
for i in range(4):
yield i
g = test()
for n in [1, 10, 5]:
g = (add(n, i) for i in g)
print(list(g))
# [15, 16, 17, 18]
5.8 异常处理
1. 示例
# 示例1
try:
val = input('请输入数字:')
num = int(val)
except Exception as e:
print('操作异常')
# 示例2
import requests
try:
ret = requests.get('http://www.baidu.com')
print(ret.text)
except Exception as e:
print('请求异常')
# 示例3
def func(a):
try:
return a.strip()
except Exception as e:
pass
return False
v = func([1, 2, 3])
print(v)
# 练习1,函数接收一个list将list中的元素每个都加100
def func(arg):
li = []
for items in arg:
if items.isdecimal():
li.append(int(items) + 100)
return li
# 写函数,接收一个list, 中全是url 访问地址,并获取结果
import requests
def func(url_list):
li = []
try:
for i in url_list:
reponse = requests.get(i)
li.append(reponse.text)
except Exception as e:
pass
return li
func(['http://www.baidu.com', 'http://www.google.com', 'http://www.bing.com'])
# 比较异常 try 的位置不同,效果也不同
import requests
def func(url_list):
li = []
for i in url_list:
try:
reponse = requests.get(i)
li.append(reponse.text)
except Exception as e:
pass
return li
func(['http://www.baidu.com', 'http://www.google.com', 'http://www.bing.com'])
# 得到的结果是text格式的文本文档
reponse = requests.get('url', useragent:xxxxxx)
2. 基本格式
try:
pass
except ValueError as e:
pass
except IndexErro as e:
pass
except Exception as e:
print(e)
finally:
print('final') # 无论对错都要执行的代码
# e 代表异常信息,是Exception类的对象,有一个错误信息
try:
int('asdf')
except Exception as e:
print(e)
try:
int('asdf')
except ValueError as e:
print(e)
try:
int('asdf')
except IndexError as e:
print(e)
# 即使遇到return 也会执行finally
def func():
try:
int('1')
return
except Exception as e:
print(e)
finally:
print('final')
3. 主动触发异常
try:
int('123')
raise Exception('错误信息') # 主动抛出异常
except Exception as e:
print(1)
# 打开一个文件,
def func():
resutl = True
try:
with open('x.log', mode='r', encoding='utf-8') as f:
data = f.read()
if 'henry' not in data:
raise Exception()
except Exception as e:
result = False
return result
4. 自定义异常
# 示例1
class MyException(Exception):
pass
try:
raise MyException('haha,错了吧')
except MyException as e:
print(e)
class MyException(Exception):
def __init__(self, message):
self.message = message
try:
raise MyExceptoin('123')
except MyException as e:
print(e.message)
☞☞☞ 古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。 ☜ ☜ ☜