华为mate10pro碎屏险手机碎屏险怎么买,揭示单纯的口水仗宣传价值在

Python 异常处理 捕获异常 - 推酷
Python 异常处理 捕获异常
0X00 什么是异常
程序在运行出错的时候就会抛出异常,异常时在正确的代码里发生的,不是代码出现了错误。下面就是一个异常
#!/usr/bin/python
#coding=utf-8
num_1 = 10
# 很明显这里是用一个数字去除以0
# 小学老师就说过0不能作为被除数
# 那么我们来看Python是如何处理这个问题的
num_3 = num_1 / num_2
print num_3
运行这个程序就会报出下面的错误,错误提示说在
这个文件的第6行,出现了一个错误
integer division or modulo by zero
也就是说Python解释器发现你试图除以0或者试图用0取模。
Traceback (most recent call last):
File &./hello.py&, line 6, in &module&
num_3 = num_1 / num_2
ZeroDivisionError: integer division or modulo by zero
这里提示的
ZeroDivisionError
就是一个异常,我们可以在后面捕获这个异常,然后进行一些处理。如果不捕获这个异常的话,程序运行到这里,异常就会直接抛出到用户界面,中断程序的运行。
0X01 自己放出一个异常
我们可以用
抛出一个自己的异常,这样我们可以在调试程序的时候判断到底出了什么错误,通过抛出的异常信息就可以判断。
#!/usr/bin/python
#coding=utf-8
name = raw_input('name: ')
if name == '':
# 姓名不允许为空
raise Exception('name is null') # 抛出一个自定义的Exception内容是name is null
= input('age : ')
if age &= 0:
# 不允许年龄小于等于0
raise Exception('age too little') # 爆出一个自顶一个Excep内容是age too little
print 'name is ' + name
print 'age is ' + str(age)
上面这段代码只是简单地输入name和age两个变量,合法的话就输出出来。我们这里运行一下试试
[root@iZ28jaak5nnZ ~]# ./hello.py
name: shawn
#合法输入的话,就可以顺利输出
name is shawn
[root@iZ28jaak5nnZ ~]# ./hello.py
# 这里变量内容为空
Traceback (most recent call last):
File &./hello.py&, line 6, in &module&
raise Exception('name is null')
# 就是在我设置的地方抛出了异常
Exception: name is null # 异常内容和类型都是我所规定的
[root@iZ28jaak5nnZ ~]# ./hello.py
name: shawn
Traceback (most recent call last):
File &./hello.py&, line 10, in &module&
raise Exception('age too little')
Exception: age too little
我们可以用这种方式在自己的代码中抛出异常,用来做中间值检测,防止中间的数据出现意外导致一些不可思议的后果。
0X02 捕获异常
我们在代码中不管是解释器自己抛出的异常还是你手动抛出的异常,都可以手动的捕获到这个异常,并做出相应的处理。这样就可以提高代码的健壮性。在Python使用
try...except...else
来捕获处理异常。
# 这里执行一些可能会抛出异常的代码
except (ExceptionA, ExceptionB, ExceptionC):
# 一个except可以捕获好多个异常
# 当抛出ABC三种异常的时候,执行这里的代码,执行完之后跳出try...except并继续执行代码
except ExceptD:
# 当抛出D异常的时候就会执行这里的代码,执行完后也跳出
except ExceptE, e:
# 当抛出E异常的时候在这里处理,e就是这个异常对象,我们可以看e中的信息
print e # 输出e
# 当抛出了一个上面两个except捕获不到的异常的时候,执行这里的操作
# 当没有异常抛出的时候执行这里的代码
# 不管代码有没有抛出异常,都会执行这里的代码
下面有一个样例,还是除0异常的样例,当除数是0的时候就抛出异常并捕获,然后处理这个异常(提示并重新输入),直到没有除0异常才计算成功并退出程序
#!/usr/bin/python
#coding=utf-8
while True:
num_1 = input('num1: ')
num_2 = input('num2: ')
num_3 = num_1 / num_2
except ZeroDivisionError:
print 'num_1 is 0 !!!'
print num_3
下面有一个运行样例
[root@iZ28jaak5nnZ ~]# ./hello.py
num_1 is 0 !!!
num_1 is 0 !!!
num_1 is 0 !!!
当然我们也可以将异常处理完了之后继续抛出,只要你需要。下面的代码和上面的是完全一样的,就只有12行的地方从continue换成了raise,意思就是抛出异常
#!/usr/bin/python
#coding=utf-8
while True:
num_1 = input('num1: ')
num_2 = input('num2: ')
num_3 = num_1 / num_2
except ZeroDivisionError:
print 'num_1 is 0 !!!'
# 只有这里是不同的,从continue换成了没有参数的raise,就是把异常继续抛出
print num_3
运行的样例就是下面这样的,执行下去之后会执行except中的处理代码,但是由于raise的存在还是会抛出这个异常
[root@iZ28jaak5nnZ ~]# ./hello.py
num_1 is 0 !!!
# 这里就是except处的处理代码
Traceback (most recent call last):
File &./hello.py&, line 9, in &module&
num_3 = num_1 / num_2
ZeroDivisionError: integer division or modulo by zero
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Python基础教程:异常、方法、属性和迭代器
8.1 基本操作
raise Exception('异常演示')
Traceback (most recent call last):
File &/xxx/07.python/project/demo/__init__.py&, line 8, in
raise Exception('异常演示')
Exception: 异常演示
内建的异常
可以在exceptions模块找到,使用dir函数列出来。
&&& import exceptions
&&& dir(exceptions)
['ArithmeticError', 'AssertionError', ...]
所有异常的基类
AttributeError
特性引用或赋值失败时引发
试图打开不存在文件(包括其他情况)时引发
IndexError
使用序列中不存在的索引
使用映射中不存在的键
找不到名字(变量)
SyntaxError
代码为错误形式
内建操作或函数应用于错误类型的对象
ValueError
内建操作或函数应用于正确类型的对象,但该对象使用不合适的值
ZeroDivisionError
除法或模除操作的第二个参数为0
8.2 自定义异常
class SomeCustomException(Exception): pass
8.3 捕捉异常
使用try/except:
x = input(&first: &)
y = input(&second: &)
except ZeroDivisionError, e:
# 访问异常对象本身
except (TypeError, NameError):
# 同时捕捉多个异常
# 向上抛出异常
The second number cant be zero!
second: &how&
Traceback (most recent call last):
File &xxx/__init__.py&, line 11, in
TypeError: unsupported operand type(s) for /: 'int' and 'str'
Traceback (most recent call last):
File &/xxx/__init__.py&, line 10, in
y = input(&second: &)
File &&, line 1, in
NameError: name 'j' is not defined
8.4 else、finally
while True:
x = input(&first: &)
y = input(&second: &)
print x / y
print '捕捉所有异常'
print '未发生异常时执行'
print &总是执行&
捕捉所有异常
未发生异常时执行
8.5 新函数
warnings.filterwarnings(actiong, &)
用于过滤警告
9. 魔法方法、属性和迭代器
9.1 准备工作
赋值语句metaclass=type放在模块最开始,或者子类化object。
class NewStyle(object):
9.2 构造方法
class FooBar:
def __init__(self):
self.somevar = 42
f = FooBar()
print f.somevar
9.2.1 重写构造方法
调用未绑定的超类构造方法
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
print 'No, tks'
class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
self.sound = 'Squawk!'
def sing(self):
print self.sound
sb = SongBird()
使用super函数
__metaclass__ = type
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
print 'No, tks'
class SongBird(Bird):
def __init__(self):
super(SongBird, self).__init__()
self.sound = 'Squawk!'
def sing(self):
print self.sound
sb = SongBird()
9.3 成员访问
9.3.1 基本的序列和映射规则
序列和映射是对象的集合。
__len_(self):返回集合中所含项目的数量。 __getitem__(self, key):返回与所给键对应的值。 __setitem__(self, key, value):设置和key相关的value。只能为可以修改的对象定义这个方法。 __delitem__(self, key):对一部分对象使用del语句时被调用,同时必须删除和元素相关的键。
对于序列,如果键是负数,从末尾开始计数。 如果键是不合适的类型,会引发TypeError异常。 如果序列是正确的类型,但超出范围,引发IndexError异常。
9.3.1 子类化列表、字典和字符串
通过子类化超类,进行扩展。
class CounterList(list):
def __init__(self, *args):
super(CounterList, self).__init__(*args)
self.counter = 0
def __getitem__(self, index):
self.counter += 1
return super(CounterList, self).__getitem__(index)
cl = CounterList(range(10))
cl.reverse()
del cl[3:6]
print cl.counter
print cl[4] + cl[2]
print cl.counter
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[9, 8, 7, 3, 2, 1, 0]
9.5.1 property函数
property函数有4个参数,分别为fget、fset、fdel和doc
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def setSize(self, size):
self.width, self.height = size
def getSize(self):
return self.width, self.height
size = property(getSize, setSize)
r = Rectangle()
r.width = 10
r.height = 5
print r.size
r.size = 150, 100
print r.width
9.5.2 静态方法和类成员方法
静态方法和类成员方法分别在创建时被装入Staticmethod类型和Classmethod类型的对象中。
class MyClass:
# 可以使用@staticmethod修饰器
def smeth():
print &this is a static method&
smeth = staticmethod(smeth)
# 可以使用@classmethod修饰器
def cmeth(cls):
print 'this is a class method of', cls
cmeth = classmethod(cmeth)
MyClass.smeth()
MyClass.cmeth()
this is a static method
this is a class method of
9.5.3 __getattr__、__setattr__
__getattribute__(self, name):当特性name被访问时自动被调用(只能在新式类中使用)。 __getattr__(self, name):当特性name被访问且对象没有相应的特性时被自动调用。 __setattr__(self, name, value):当试图给特性name赋值时会被自动调用。 __delattr__(self, name):当试图删除特性name时被自动调用。
9.5 迭代器
9.5.1 迭代器规则
__iter__方法返回一个迭代器(iterator),如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def next(self):
self.a, self.b = self.b, self.a + self.b
return self.a
def __iter__(self):
return self
fibs = Fibs()
for f in fibs:
if f & 1000:
9.5.2 从迭代器得到序列
示例:使用list构造方法显式地将迭代器转化为列表
class TestIterator:
def next(self):
self.value += 1
if self.value & 10:
raise StopIteration
return self.value
def __iter__(self):
return self
ti = TestIterator()
print list(ti)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
9.5 生成器
生成器是一种用普通的函数语法定义的迭代器。
9.5.1 创建生成器
任何包含yield语句的函数称为生成器。每次产生值(使用yield语句),函数就会被冻结:即函数停在那点等待被激活。函数被激活后就从停止的那点开始执行。
def flattern(nested):
for sublist in nested:
for element in sublist:
yield element
nested = [[1, 2], [3, 4], [5]]
for num in flattern(nested):
print list(flattern(nested))
[1, 2, 3, 4, 5]
9.5.2 递归生成器
def flattern(nested):
for sublist in nested:
for element in flattern(sublist):
yield element
except TypeError:
yield nested
print list(flattern([[[1], 2], 3, 4, [5, [6, 7]], 8]))
[1, 2, 3, 4, 5, 6, 7, 8]
9.5.3 生成器方法
生成器和&外部世界&进行交流的渠道,要注意以下两点:
外部作用域访问生成器的send方法,就像访问next方法一样,只不过前者使用一个参数(要发送的&消息&&&任意对象)。 在内部则挂起生成器,yield现在作为表达式而不是语句使用,换句话说,当生成器重新运行的时候,yield方法返回一个值,也就是外部通过send方法发送的值。如果next方法被使用,那么yield方法返回None。
def repeater(value):
while True:
new = (yield value)
if new is not None:
value = new
r = repeater(43)
print r.next()
print r.send(&Hello, world!&)
Hello, world!
生成器还有其他两个方法:
throw方法用于在生成器内引发一个异常。 close方法用于停止生成器。
9.5.4 模拟生成器
使用普通的函数模拟生成器。
def flattern(nested):
result = []
try: nested + ' '
except TypeError: pass
else: raise TypeError
for sublist in nested:
for element in flattern(sublist):
result.append(element)
except TypeError:
result.append(nested)
return result
print list(flattern([[[1], 2], 3, 4, [5, [6, 7]], 8]))
[1, 2, 3, 4, 5, 6, 7, 8]
9.6 新函数
从一个可迭代的对象得到迭代器
property(fget, fset, fdel, doc)
返回一个属性,所有的参数都是可选的
super(class, obj)
返回一个类的超类的绑定实例Python 错误和异常小结
字体:[ ] 类型:转载 时间:
这不是一篇关于Python异常的全面介绍的文章,这只是在学习Python异常后的一篇笔记式的记录和小结性质的文章
事先说明哦,这不是一篇关于Python异常的全面介绍的文章,这只是在学习Python异常后的一篇笔记式的记录和小结性质的文章。什么?你还不知道什么是异常,额... 1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不用Python了)。
尝试访问一个没有申明的变量
ZeroDivisionError
SyntaxError
IndexError
索引超出序列范围
请求一个不存在的字典关键字
输入输出错误(比如你要读的文件不存在)
AttributeError
尝试访问未知的对象属性
ValueError
传给函数的参数类型不正确,比如给int()函数传入字符串形
2.捕获异常
&&& Python完整的捕获异常的语句有点像:
代码如下:try:&&& try_suiteexcept Exception1,Exception2,...,Argument:&&& exception_suite......&& #other exception blockelse:&&& no_exceptions_detected_suitefinally:&&& always_execute_suite
额...是不是很复杂?当然,当我们要捕获异常的时候,并不是必须要按照上面那种格式完全写下来,我们可以丢掉else语句,或者finally语句;甚至不要exception语句,而保留finally语句。额,晕了?好吧,下面,我们就来一一说明啦。
2.1.try...except...语句
&&& try_suite不消我说大家也知道,是我们需要进行捕获异常的代码。而except语句是关键,我们try捕获了代码段try_suite里的异常后,将交给except来处理。
&&& try...except语句最简单的形式如下:
代码如下:try:&&& try_suiteexcept:&&& exception block
上面except子句不跟任何异常和异常参数,所以无论try捕获了任何异常,都将交给except子句的exception block来处理。如果我们要处理特定的异常,比如说,我们只想处理除零异常,如果其他异常出现,就让其抛出不做处理,该怎么办呢?这个时候,我们就要给except子句传入异常参数啦!那个ExceptionN就是我们要给except子句的异常类(请参考异常类那个表格),表示如果捕获到这类异常,就交给这个except子句来处理。比如:
代码如下:try:&&& try_suiteexcept Exception:&&& exception block
举个例子:
代码如下:&&& try:...&&&& res = 2/0... except ZeroDivisionError:...&&&& print "Error:Divisor must not be zero!"... Error:Divisor must not be zero!
看,我们真的捕获到了ZeroDivisionError异常!那如果我想捕获并处理多个异常怎么办呢?有两种办法,一种是给一个except子句传入多个异常类参数,另外一种是写多个except子句,每个子句都传入你想要处理的异常类参数。甚至,这两种用法可以混搭呢!下面我就来举个例子。
代码如下:try:&&& floatnum = float(raw_input("Please input a float:"))&&& intnum = int(floatnum)&&& print 100/intnumexcept ZeroDivisionError:&&& print "Error:you must input a float num which is large or equal then 1!"except ValueError:&&& print "Error:you must input a float num!"
[root@Cherish tmp]# python test.py Please input a float:fjiaError:you must input a float num![root@Cherish tmp]# python test.py Please input a float:0.9999Error:you must input a float num which is large or equal then 1![root@Cherish tmp]# python test.py Please input a float:25.0914
上面的例子大家一看都懂,就不再解释了。只要大家明白,我们的except可以处理一种异常,多种异常,甚至所有异常就可以了。
&&& 大家可能注意到了,我们还没解释except子句后面那个Argument是什么东西?别着急,听我一一道来。这个Argument其实是一个异常类的实例(别告诉我你不知到什么是实例),包含了来自异常代码的诊断信息。也就是说,如果你捕获了一个异常,你就可以通过这个异常类的实例来获取更多的关于这个异常的信息。例如:
代码如下:&&& try:...&&&& 1/0... except ZeroDivisionError,reason:...&&&& pass... &&& type(reason)&type 'exceptions.ZeroDivisionError'&&&& print reasoninteger division or modulo by zero&&& reasonZeroDivisionError('integer division or modulo by zero',)&&& reason.__class__&type 'exceptions.ZeroDivisionError'&&&& reason.__class__.__doc__'Second argument to a division or modulo operation was zero.'&&& reason.__class__.__name__'ZeroDivisionError'
上面这个例子,我们捕获了除零异常,但是什么都没做。那个reason就是异常类ZeroDivisionError的实例,通过type就可以看出。
2.2try ... except...else语句&&& 现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:
代码如下:&&& import syslog&&& try:...&&&& f = open("/root/test.py")... except IOError,e:...&&&& syslog.syslog(syslog.LOG_ERR,"%s"%e)... else:...&&&& syslog.syslog(syslog.LOG_INFO,"no exception caught\n")... &&& f.close()
2.3 finally子句&&& finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。
例如2.2的例子,如果出现其他异常,无法捕获,程序异常退出,那么文件 f 就没有被正常关闭。这不是我们所希望看到的结果,但是如果我们把f.close语句放到finally语句中,无论是否有异常,都会正常关闭这个文件,岂不是很 妙
代码如下:&&& import syslog&&& try:...&&&& f = open("/root/test.py")... except IOError,e:...&&&& syslog.syslog(syslog.LOG_ERR,"%s"%e)... else:...&&&& syslog.syslog(syslog.LOG_INFO,"no exception caught\n")... finally: &&& & & f.close()
&大家看到了没,我们上面那个例子竟然用到了try,except,else,finally这四个子句!:-),是不是很有趣?到现在,你就基本上已经学会了如何在Python中捕获常规异常并处理之。
3.两个特殊的处理异常的简便方法
3.1断言(assert)&&& 什么是断言,先看语法:
代码如下:assert expression[,reason]
其中assert是断言的关键字。执行该语句的时候,先判断表达式expression,如果表达式为真,则什么都不做;如果表达式不为真,则抛出异常。reason跟我们之前谈到的异常类的实例一样。不懂?没关系,举例子!最实在!
代码如下:&&& assert len('love') == len('like')&&& assert 1==1&&& assert 1==2,"1 is not equal 2!"Traceback (most recent call last):& File "&stdin&", line 1, in &module&AssertionError: 1 is not equal 2!
我们可以看到,如果assert后面的表达式为真,则什么都不做,如果不为真,就会抛出AssertionErro异常,而且我们传进去的字符串会作为异常类的实例的具体信息存在。其实,assert异常也可以被try块捕获:
代码如下:&&& try:...&&&& assert 1 == 2 , "1 is not equal 2!"... except AssertionError,reason:...&&&& print "%s:%s"%(reason.__class__.__name__,reason)... AssertionError:1 is not equal 2!&&& type(reason)&type 'exceptions.AssertionError'&
3.2.上下文管理(with语句)&& 如果你使用try,except,finally代码仅仅是为了保证共享资源(如文件,数据)的唯一分配,并在任务结束后释放它,那么你就有福了!这个with语句可以让你从try,except,finally中解放出来!语法如下:
代码如下:with context_expr [as var]:&&& with_suite
是不是不明白?很正常,举个例子来!
代码如下:&&& with open('/root/test.py') as f:...&&&& for line in f:...&&&&&&&& print line
上面这几行代码干了什么?&&& (1)打开文件/root/test.py&&& (2)将文件对象赋值给& f&&& (3)将文件所有行输出&&&& (4)无论代码中是否出现异常,Python都会为我们关闭这个文件,我们不需要关心这些细节。&&& 这下,是不是明白了,使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表:file
decimal.Contextthread.LockTypethreading.Lockthreading.RLockthreading.Conditionthreading.Semaphorethreading.BoundedSemaphore
&&& 至于什么是上下文管理协议,如果你不只关心怎么用with,以及哪些对象可以使用with,那么我们就不比太关心这个问题:)
4.抛出异常(raise)
&&& 如果我们想要在自己编写的程序中主动抛出异常,该怎么办呢?raise语句可以帮助我们达到目的。其基本语法如下:
代码如下:raise [SomeException [, args [,traceback]]
第一个参数,SomeException必须是一个异常类,或异常类的实例 &&& 第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。&&& 第三个参数traceback很少用,主要是用来提供一个跟中记录对象(traceback)&&& 下面我们就来举几个例子。
代码如下:&&& raise NameErrorTraceback (most recent call last):& File "&stdin&", line 1, in &module&NameError&&& raise NameError()& #异常类的实例Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError&&& raise NameError,("There is a name error","in test.py")Traceback (most recent call last):& File "&stdin&", line 1, in &module&&&& raise NameError("There is a name error","in test.py")& #注意跟上面一个例子的区别Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError: ('There is a name error', 'in test.py')&&& raise NameError,NameError("There is a name error","in test.py")& #注意跟上面一个例子的区别Traceback (most recent call last):& File "&stdin&", line 1, in &module&NameError: ('There is a name error', 'in test.py')
其实,我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。如上面第三个例子。
5.异常和sys模块
&&& 另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)
代码如下:&&& try:...&&&& 1/0... except:...&&&& import sys...&&&& tuple = sys.exc_info()... &&& print tuple(&type 'exceptions.ZeroDivisionError'&, ZeroDivisionError('integer division or modulo by zero',), &traceback object at 0x7f538a318b48&)&&& for i in tuple:...&&&& print i... &type 'exceptions.ZeroDivisionError'& #异常类 & &integer division or modulo by zero #异常类的实例&traceback object at 0x7f538a318b48& #跟踪记录对象
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具python 如何优雅的处理大量异常语句?
我需要用bs4来分析一个html,需要写很多 提取语句,大概几十条,格式如下
twitter_url = summary_soup.find('a','twitter_url').get('href')
facebook_url = summary_soup.find('a','facebook_url').get('href')
linkedin_url = summary_soup.find('a','linkedin_url').get('href')
name = summary_soup.find('div', class_='name').find('a').string
.find但是每个语句都有可能出异常,如果每个语句都加上try except 就太繁琐了,有没有什么好的方法处理每条语句,出异常赋值为None,不中断程序
自己def一个方法,把每一个find.get改为用调用方法。这是一种常见的处理方式,甚至你都可以认为这是重构中的“抽取方法”
看来你不了解python的get操作,dict 的get都是可以操作的。如果key不存在,返回None
--- 共有 2 条评论 ---
: 一般是,先if一下,看看是不是None。然后再get
问题不在dict
summary_soup.find('a','twitter_url')可能返回一个soup对象,也有可能返回None,前者可以使用get,后者产生异常
再写一个wrapper函数,把find写进去不就行了}

我要回帖

更多关于 华为mate10碎屏险 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信