此篇文章主要介绍以下几个知识点:
1、类、对象的从属检查
2、异常处理
3、反射
4、单例模式
类、对象的从属检查
命令格式:isinstance(obj, cls)
描述:检查obj是否是由类cls创建的对象,也可以用于判断数据类型。
例子:n1 = 123 #定义一个 整数 类型的变量
s1 = ‘123’ #定义一个 字符串 类型的变量
l1 = [‘123’] #定义一个 列表 类型的变量
d1 = {‘k1′:’123’} #定义一个 字典 类型的变量
class Cls: #定义一个类
pass
c1 = Cls() #根据定义的类创建一个对象
print isinstance(n1,int) #检查n1是否是由int类创建的对象,也就是检查n1是否是整数数据类型
print isinstance(s1,str) #检查s1是否是由str类创建的对象,也就是检查s1是否是字符串数据类型
print isinstance(l1,list) #检查l1是否是由list类创建的对象,也就是检查l1是否是列表数据类型
print isinstance(d1,dict) #检查d1是否是由dict类创建的对象,也就是检查d1是否是字典数据类型
print isinstance(c1,Cls) #检查c1是否是由Cls类创建的对象
#执行结果:
True
True
True
True
True
命令格式:issubclass(sub,super)
描述:检查sub类是否是super类(基类)的派生类
例子:class F: #定义一个基类
pass
class S(F): #定义一个类S继承基类F
pass
print issubclass(S,F) #判断S类是否是F类的派生类
print issubclass(F,S) #判断F类是否是S类的派生类
#执行结果:
True
False
异常处理
所有的程序在运行的时候,都可能会出现各种各样的错误(比如:某个方法需要一个整数类型的参数,可是用户却传入了一个字符串类型的参数。),而一个优秀的程序员的基本素质就是在编写代码的时候预先判断到错误的出现,并进行相应的处理,这就需要用到异常处理。
命令格式:
try:
pass#主逻辑代码块
raise Exception(‘msg’)#主动触发一个异常
except Exception,e:#捕获异常,变量e的值是异常描述信息
pass#捕获异常后执行的代码
else:
pass#未捕获到任何异常时执行的代码
finally:
pass#最后总会执行的代码
描述:基本的语法是在try下代码块中书写主逻辑代码,然后定义捕获的异常以及在捕获到异常后需要执行的代码,还可以定义当未捕获到任何异常时执行的代码。最后可以定义当以上代码都执行完成后需要执行的代码。
raise 用法:
命令格式:raise Exception(‘自定义的异常描述信息,也就是变量e的值’)
自定义一个希望被捕获的异常信息,一般用于避免程序频繁的手动print错误信息。
Exception的常用类型:
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
捕获异常的例子:try:
L = [1,2,3]
L[4] #列表L的下标最大是2,取下标为4的值肯定会出现异常
except Exception,e: #捕获到任何异常时执行此代码块
print ‘Get error message: ‘,e
else: #未捕获到任何异常时执行此代码块
print ‘No error’
finally: #最后执行此代码块
print ‘Process is done’
#执行结果:
Get error message: list index out of range
Process is done
捕获指定异常的例子:try:
L = [1,2,3]
L[4]
except IndexError,e: #只捕获类型为IndexError的异常
print ‘Get error message: ‘,e
else:
print ‘No error’
finally:
print ‘Process is done’
#执行结果:
Get error message: list index out of range
Process is done
未捕获异常的例子:try:
L = [1,2,3]
L[1] #下标存在,所以不会有异常
except Exception,e:
print ‘Get error message: ‘,e
else:
print ‘No error’
finally:
print ‘Process is done’
#执行结果:
No error
Process is done
反射
python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,这四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
命令格式:
hasattr(容器,查找条件) #去某个容器(模块)中,查找是否有满足条件的成员
getattr(容器,获取条件) #去某个容器(模块)中,查找是否有满足条件的成员,有则返回该成员
setattr(容器,成员,值) #去某个容器(模块)中,若成员存在,则修改其值,若不存在,则创建
delattr(容器,删除条件) #去某个容器(模块)中,删除满足条件的成员。
例子:class test:
name = ‘123’
#hasattr
print hasattr(test,’name’) #执行结果为True
#getattr
ret = getattr(test,’name’) #如果name是一个函数,那么ret的值就是该函数
print ret #执行结果为123
#setattr
setattr(test,’name’,’456′)
print getattr(test,’name’) #执行结果为456
#delattr
delattr(test,’name’)
print hasattr(test,’name’) #执行结果为False
单例模式
一个类在内存中只创建一个对象,供所有调用者使用,避免内存浪费。
适用场景:实现单一功能的类,但同时又必须创建多个对象。
例子:class Foo:
__instance = None #定义一个私有静态字段用于判断类是否被用来创建过对象
@classmethod
def instance(cls): #定义一个类方法
if cls.__instance: #如果静态字段有值,则说明已创建过对象,则返回该对象
return cls.__instance
else: #如果静态字段没有值,则说明未创建过对象,那么就创建它
cls.__instance = Foo() #创建对象
return cls.__instance #创建完成后返回创建好的对象
print ‘Single test’
obj = Foo.instance() #使用单例模式创建对象1
print id(obj)
obj2 = Foo.instance() #使用单例模式创建对象2
print id(obj2)
obj3 = Foo.instance() #使用单例模式创建对象3
print id(obj3)
print ‘Normal test’
obj4 = Foo() #使用正常方式创建对象4
print id(obj4)
obj5 = Foo() #使用正常方式创建对象5
print id(obj5)
obj6 = Foo() #使用正常方式创建对象6
print id(obj6)
#执行结果
Single test #使用单例模式创建的对象内存ID号相同,说明只创建了一个对象
39110792
39110792
39110792
Normal test #使用正常方式创建的对象内存ID号不同,说明创建了多个对象
39811464
39811528
39811592
文章部分内容引用自本人的Python老师武沛齐的博客,由于原博客地址不方便公开,所以在此说明。