最近在补 Python 进阶的内容,学习资源来自:Python 进阶,是《Intermediate Python》的中译本。这里面的一些内容,对于我来说是比较容易忽略的知识点。
对象自省(Inrospection)
在 Python 中,对象自省也是其强项之一。自省指的是在运行时判断一个对象的类型的能力。下面可以看看 Python 中一些常用的自省能力。
:返回一个列表。用来查看对象所拥有的属性和方法。
In[6]:a=1
In[7]:dir(a)
Out[7]:
['__abs__',
'__add__',
'__and__',
'__bool__',
'__ceil__',
'__class__',
'__delattr__',
'__dir__',
'__divmod__',
'__doc__',
'__eq__',
'__float__',
'__floor__',
'__floordiv__',
'__format__',
'__ge__',
'__getattribute__',
'__getnewargs__',
'__gt__',
'__hash__',
'__index__',
'__init__',
'__init_subclass__',
'__int__',
'__invert__',
'__le__',
'__lshift__',
.....]
:返回一个对象的类型。
In[9]:a="hello"
In[10]:type(a)
Out[10]:str
:返回任意不同种类对象的唯一 ID
In[11]:name="caoqi95"
In[12]:id(name)
Out[12]:1875152854352
In[13]:age=23
In[14]:id(age)
Out[14]:1572630272
Python 中还有很多其他方法用于自省。有需要的话,可以看看文档说明。
解析式(Comprehension)
解析式是 Python 独有的特性。其是可以从一个数据结构构建另一个新的数据结构序列的结构体。一共有 3 种类型,包括列表,字典和集合解析式。
列表解析式列表解析式很常见,如下所示:
multiples= [iforiinrange(30)ifi%3is]
其可以简化循环的代码:
squared= []
foriinrange(10):
squared.append(i)
# 简化
squared= [i**2foriinrange(10)]
字典解析式字典解析式最常用的就是快速兑换字典的键和值:
{v:kfork,vinsome_dict.item()}
集合解析式它们跟列表推导式也是类似的。 唯一的区别在于它们使用大括号。 如下所示:
squared= {x**2forxin[1,1,2]}
异常处理
通常在一些代码中见到的都是单个错误的处理,如下所示:
try:
file=open('test.txt','rb')
exceptIOErrorase:
print('An IOError occurred. {}'.format(e.args[-1]))
其实,还可以同时处理多个错误,下面有 3 种方法可以用来处理多个异常。
把所有可能发生的异常都写在一个元祖里:
try:
file=open('test.txt','rb')
except(IOError,EOFError)ase:
print("An error occurred. {}".format(e.args[-1]))
每个异常都起一个:
try:
file=open('test.txt','rb')
exceptEOFErrorase:
print("An EOF error occurred.")
raisee
exceptIOErrorase:
print("An error occurred.")
raisee
捕捉所有异常:
try:
file=open('test.txt','rb')
exceptException:
raise
对于异常处理,除了语句外,还有其他语句。
从句
try:
file=open('test.txt','rb')
exceptIOErrorase:
print('An IOError occurred. {}'.format(e.args[-1]))
finally:
print("This would be printed whether or not an exception occurred!")
从句后面的代码不管异常是否触发,都将会被执行。通常可以用来处理一些善后工作。
语句
try:
print('I am sure no exception is going to occur!')
except Exception:
print('exception')
else:
# 这里的代码只会在 try 语句里没有触发异常时运行,
# 但是这里的异常将 *不会* 被捕获
print('This would only run if no exception occurs. And an error here '
'would NOT be caught.')
finally:
print('This would be printed in every case.')
如果想在没有触发异常的时候执行一些代码,可以很轻松地通过一个从句来实现。其中从句只会在没有异常的情况下执行,而且它会在语句之前执行。
for - else 结构
我们一般见到的循环会如下所示,但其实它还会有结构。
foriinrange(10):
print(i)
下面来看看循环的结构:
foriinrange(2,10):
ifi>10:# 此条件在整个循环范围外,因此不会 break
break
else:
print('Hello World')
foriinrange(2,10):
ifi>5:# 会 break,未完全执行完整个循环
break
else:
print('Hello World')
可以看出,在循环中,如果没有从任何一个中退出,则会执行和对应的。即后面的代码只会在循环正常结束的时候执行。
建议避免在生产环境中使用结构,因为其本身的歧义以及和完全相反的运作方式,会影响可阅读性。
open 函数
我们都是到函数的用法如下:
withopen('file_name','r+')asf:
data=f.read()
其实可以写成下面的形式:
f=open('file_name','r+')
data=f.read()
f.close()
为什么都使用第一种形式,而不是第二种形式?这是有原因的。首先,函数返回的是一个文件句柄,从操作系统托付给 Python 程序。在处理完成之后,需要归还这个文件句柄,这样才不会超过使用句柄的次数上限。其次,之后在文件 read 成功的条件下,才能被调用。一旦有任何异常,就不能被调用。所以,为了确保不触发任何异常,就会写成第一种形式。
领取专属 10元无门槛券
私享最新 技术干货