python面向对象的内置函数和异常
内置函数
str:
__str__方法会在对象被打印时自动触发,print功能打印的就是它的返回值,
我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
p=People('lili',18)
print(p) #触发p.__str__(),拿到返回值后进行打印
# <Name:lili Age:18>
del:
__del__会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,
所以当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,
但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,
Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
self.f = open('a', mode='r')
# 1. 手动删除对象执行
# 2. 应该程序执行完毕自动触发
def __del__(self):
print("__del__")
self.f.close()
obj = Student('ly', 19)
# del obj
print("end----->")
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
class Foo(object):
pass
obj = Foo()
isinstance(obj, Foo)
issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
setattr,delattr,getattr:
class Foo:
x=1
def __init__(self,y):
self.y=y
def __getattr__(self, item):
print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value #这就无限递归了,你好好想想
# self.__dict__[key]=value #应该使用它
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了
self.__dict__.pop(item)
#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
getattribute:不管存不存在我都运行
class Foo:
def __init__(self,x):
self.x=x
def __getattribute__(self, item):
print('不管是否存在,我都会执行')
f1=Foo(10)
f1.x
f1.xxxxxx
setitem,__getitem,delitem:
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
print(self.__dict__[item])
def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item)
f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)
call:对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
异常
1、什么是异常
异常是程序发生错误的信号。程序一旦出现错误,便会产生一个异常,
若程序中没有处理它,就会抛出该异常,程序的运行也随之终止
2、异常的分类:
错误分成两种,
一种是语法上的错误SyntaxError,这种错误应该在程序运行前就修改正确:
如:print(111 后面的括号不加就是一个语法错误SyntaxError
另一种就是逻辑错误,常见的逻辑错误如:
# TypeError:数字类型无法与字符串类型相加
1+’2’
# ValueError:当字符串包含有非数字的值时,无法转成int类型
num=input(">>: ") #输入hello
int(num)
# NameError:引用了一个不存在的名字x
x
# IndexError:索引超出列表的限制
l=['egon','aa']
l[3]
# KeyError:引用了一个不存在的key
dic={'name':'egon'}
dic['age']
# AttributeError:引用的属性不存在
class Foo:
pass
Foo.x
# ZeroDivisionError:除数不能为0
1/0
3、异常处理
分别有下面几种处理形式:
1.为了保证程序的容错性与可靠性,即在遇到错误时有相应的处理机制不会任由程序崩溃掉,我们需要对异常进行处理,处理的基本形式为
try:
被检测的代码块
except 异常类型:
检测到异常,就执行这个位置的逻辑
2.如果我们想分别用不同的逻辑处理,需要用到多分支的except(类似于多分支的elif,从上到下依次匹配,匹配成功一次便不再匹配其他)
try:
被检测的代码块
except NameError:
触发NameError时对应的处理逻辑
except IndexError:
触发IndexError时对应的处理逻辑
except KeyError:
触发KeyError时对应的处理逻辑
3.如果我们想多种类型的异常统一用一种逻辑处理,可以将多个异常放到一个元组内,用一个except匹配
try:
被检测的代码块
except (NameError,IndexError,TypeError):
触发NameError或IndexError或TypeError时对应的处理逻辑
4.如果我们想捕获所有异常并用一种逻辑处理,Python提供了一个万能异常类型Exception
try:
被检测的代码块
except NameError:
触发NameError时对应的处理逻辑
except IndexError:
触发IndexError时对应的处理逻辑
except Exception:
其他类型的异常统一用此处的逻辑处理
5.在多分支except之后还可以跟一个else(else必须跟在except之后,不能单独存在),
只有在被检测的代码块没有触发任何异常的情况下才会执行else的子代码块
try:
被检测的代码块
except 异常类型1:
pass
except 异常类型2:
pass
......
else:
没有异常发生时执行的代码块
4、何时使用异常处理
1.如果错误发生的条件是“可预知的”,我们应该用if来进行”预防”,如下
age=input('input your age>>: ').strip()
if age.isdigit(): # 可预知只有满足字符串age是数字的条件,int(age)才不会触发异常,
age=int(age)
else:
print('You must enter the number')
2.如果错误发生的条件“不可预知”,即异常一定会触发,
那么我们才应该使用try...except语句来处理。

浙公网安备 33010602011771号