面向对象第四讲
面向对象第四讲
mixins机制
分主类和辅类 继承辅类就有辅类的功能,不影响子类的使用
命名方式, 以Mixin,able, 为结尾
辅类在主类的左边
class Vehicle():
def run(self):
pass
def driver(self): # 驾驶员
pass
class FlyMixin():
def fly(self):
pass
class Car(Vehicle):
pass
class Automobile(Vehicle): # 汽车
pass
class Airplane(FlyMixin, Vehicle): # 飞机
pass
"""
如上代码,,汽车,轿车,飞机都有 Vehicle这个类的属性,但是飞机有飞的属性,所以把飞这个属性单独拿出来设置成辅类
"""
内置函数
内置函数就是不用去调用,当满足一些条件后自动执行的代码,内置函数有很多,这里只列举几个常用的
-
str
class Student(): def __init__(self, name, age): self.name = name self.age = age def __str__(self): print('打印对象的时候会自动触发这个函数的运行,返回值必须是一个字符串') return f'{self.name}, {self.age}' obj = Student('egon', 10) print(obj) ========================================> 打印对象的时候会自动触发这个函数的运行,返回值必须是一个字符串 egon, 10 """ __str__这个函数只有在打印对象的时候才会触发,而且返回结果只能是字符串。 如果没用这个方法,打印对象的结果应该是一个内存地址 """ -
del
class Student(): def __init__(self, name, age): self.name = name self.age = age def __del__(self): print('del is running') print('1.手动删除对象时执行 2.应用程序执行完毕时自动触发') obj = Student('egon', 10) del obj print('end ==================') ============================================> del is running 1.手动删除对象时执行 2.应用程序执行完毕时自动触发 end ================== class Student(): def __init__(self, name, age): self.name = name self.age = age def __del__(self): print('del is running') print('1.手动删除对象时执行 2.应用程序执行完毕时自动触发') obj = Student('egon', 10) print('end ==================') ==========================================> end ================== del is running 1.手动删除对象时执行 2.应用程序执行完毕时自动触发 """ 通过上述两种打印结果得: 该函数在删除对象时会自动触发 程序运行结束的时候,也会自动触发这个函数的运行 """ -
isinstance
class Student(): def __init__(self, name, age): self.name = name self.age = age class Course(): def __init__(self, name): self.name = name obj1 = Course('python') obj = Student('egon', 10) print(isinstance(obj, Student)) print(isinstance(obj1, Student)) """ 这个内置函数是用来检查,这个对象是不是这个类实例出来的 """ -
issubclass
class People(): pass class Student(People): def __init__(self, name, age): self.name = name self.age = age class Course(): def __init__(self, name): self.name = name print(issubclass(Student, People)) print(issubclass(Course, People)) """ 此方法是判断这个类是不是另外一个类的子类 """ -
getattr, setattr,delattr
class Foo: x=1 def __init__(self,y): self.y=y def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 self.__dict__[key]=value #应该使用它 f = Foo(2) f.z = 1 f.x = 111 print(f.__dict__) =====================================> ----> from setattr ----> from setattr ----> from setattr {'y': 2, 'z': 1, 'x': 111} """ 由上可以得出,这个方法在实例化,增加,修改数据属性的时候会自动触发, 查看用 self.__dict__[key]=value """ class Foo: x=1 def __init__(self,y): self.y=y def __getattr__(self, item): print('----> from getattr:你找的属性不存在') obj = Foo(1) obj.m """ 当你访问的这个属性不存在的时候会自动触发该方法 """ class Foo: x = 1 def __init__(self, y): self.y = y def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 self.__dict__.pop(item) # 这里弹出的是对象属性,不是类属性,因为是对象用__dict__ obj = Foo(111) del obj.y """ 由此可以得出,该方法在执行删除属性的时候会自动触发 """ -
call
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__ is running') obj = Foo() obj() """ 这个方法在对象加括号的时候执行 """
反射
反射就是通过字符串操作类属性或者方法
class Student():
school = 'sh'
def __init__(self, name):
self.name = name
def func(self):
print('func is running')
obj = Student('egon')
print(hasattr(obj, 'school')) # 判断obj对象有没有'school'这个属性,注意这里是字符串
print(getattr(obj, 'school')) # 拿到对象obj下面的school属性
print(getattr(obj, 's', None)) # 如果obj对象下面有这个属性就拿到,没用会报错,不过可以加第三个参数,没有这个属性的时候会返回第三个参数,一般是None
print(getattr(obj, 'func')) # 拿到obj下面的func函数属性,拿到的是一个函数的内存地址,加括号可以调用
getattr(obj, 'func')()
setattr(obj, 'school', 123123234) # 修改obj对象下面school的值
delattr(obj, 'name') # 这个是删除对象obj下面的name属性
delattr(Student, 'school') # 删除Student类下面的school属性
因为python一切皆对象,所以试一下模块是不是也支持这个方法
import time
print(getattr(time, 'time')())
异常
异常就是错误发生的信号,当遇到这个信号就会抛出异常,并且此后的代码不在执行
为什么要用异常:
增加了程序的可靠性,健壮性
语法:
try:
# 被监测的代码1
# 被监测的代码1
# 被监测的代码1
# 被监测的代码1
# 被监测的代码1
pass
except 异常信息1 as e:
# 捕捉到异常信息
except 异常信息2 as e
# 捕捉到异常信息
except 异常信息3 as e
# 捕捉到异常信息
except 异常信息4 as e
pass
except Exception as e:
pass
else:
print("当被监测的代码没有异常时候执行")
finally:
print("不管有没有异常都会执行的")
断言
raise
if 1 < 2:
raise Exception('异常')
"""
用这个方法,可以返回返回指定异常,来明确地触发异常, raise后必须是一个异常的类或者是异常的实例,
异常会打印到终端
"""
assert
print(1)
print(2)
assert isinstance(18,int)
assert isinstance(18,str)
print(3)
print(4)
"""
若assert后面的语句成立,则继续执行,负责在此抛出异常
"""
自定义异常
class Myecxeption(BaseException):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return '异常信息:%s' % self.msg
obj = Myecxeption('自定义的异常')
raise Myecxeption('自定义异常')
# print(obj)
=====================>
__main__.Myecxeption: 异常信息:自定义异常
浙公网安备 33010602011771号