Python day12 13
今天学习了类的继承与多态,类装饰器与带参数的函数装饰器,单继承,单例类,元类,抛出异常:try,except,finally
继承
调用一个子类的方法时,总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
继承:
- 定义一个父类
- 定义子类继承父类
A. 继承父类非私有的属性和方法
B. 如果子类定义了一个跟父类相同属性,先找子类的属性,然后找父类
C. 如果父类与子类有相同方法,则认为子类重写了此方法(重写:override 覆盖)
————————————例题————————————————————————————————
class Animal:
type1 = '动物'
def __init__(self):
self.name = '花花'
print('----->Animal')
def run(self):
print('正在奔跑....')
def eat(self):
print('喜欢吃...')
def __str__(self):
return '当前类型:{}'.format(Animal.type1)
class Dog(Animal):
type1 = '狗'
def __init__(self, name, color):
# 调用父类的__init__方法
Animal.__init__(self)
self.name = name
self.color = color
def see_home(self):
print('看家高手....')
def eat(self):
print('喜欢啃骨头...')
d = Dog('大黄', '黄色') #----->Animal
d.run()#正在奔跑.... 继承
d.eat()#喜欢啃骨头...,重写,方法覆盖
d.see_home()#看家高手....
print(d.name)#大黄,继承父类属性,可以直接调用
print(d)#当前类型:动物 __str__语句输出
多继承
新市类:采用C3算法:与广度优先的算法结果恰巧相同,但也只是恰巧相同,不等于就是广度优先的算法。
class A:
def __init__(self):
pass
class B(A):
def __init__(self):
pass
class C(B):
def __init__(self):
pass
class D(C,A):
pass
print(D.mro())
顺序:[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
多态
多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度) 多态性:一种调用方式,不同的执行效果
宠物类可以分为狗类,猫类
class Pet:
type = '宠物'
def __init__(self, pname, color, age):
self.pname = pname
self.color = color
self.age = age
def __str__(self):
return '当前类型是:{},宠物名:{}'.format(self.type, self.pname)
class Dog(Pet):
type = '狗'
def see_house(self):
print('特长看家...')
class Cat(Pet):
type = '猫'
def catch_mouse(self):
print('特长抓老鼠....')
```python
# has a 包含
class Student:
def __init__(self,sno,sname):
self.sno=sno
self.name=sname
def study(self,sno):
print('good good study')
class Pupil(Student):
def __init__(self,age):
# Student.__init__(self,1,'校长')
super(Pupil,self).__init__('','lll')
self.age=age
def study(self,sno):
self.sno=sno
print('序号为{},{}岁的{}在打野'.format(self.sno,self.age,self.name))
student=Student(0,'阿萨')
pupil=Pupil(15)
pupil.study(12)
宠物商店:
issubclass(Cat,(Pet,)) ---> issubclass(类名,(父类1,父类2,。。))
isinstance(pet,Pet)
class PetShop:
def __init__(self, name):
self.name = name
self.pets = set()
# 动作
def save_pet(self, pet):
# print(isinstance(pet, Pet))
if isinstance(pet, Pet):**********************可以是pet对象,不限制任何类型,多肽的体现
self.pets.add(pet) *******列表里添加对象,包含
print('添加成功!')
else:
print('不是宠物不收留!')
def sale_pet(self, pet):
if isinstance(pet, Pet): ****************可以是pet对象,不限制任何类型
self.pets.discard(pet)
print('宠物减少')
else:
print('不是宠物不收留!')
class Pet:
type = '宠物'
def __init__(self, pname, color, age):
self.pname = pname
self.color = color
self.age = age
def __str__(self):
return '当前类型是:{},宠物名:{}'.format(self.type, self.pname)
class Cat(Pet):
type = '猫'
# 创建对象
shop = PetShop('爱宠')
# pet = Pet()
cat = Cat('花花', '黄色', 2)
shop.save_pet(cat) # pet =cat
类装饰器(含带参数)
既可以装函数也可以装类
类似函数装饰器
class A:
def __init__(self,f):
self.f=f
def __call__(self, *args, **kwargs):
print('*******')
self.f()
@A #func1=A(func1)
def func1():
print('装饰器')
func1()
#*******
#装饰器
**********带参数
class A():
def __init__(self,f):
print('我是参数',f)
def __call__(self,func,*args,**kwargs):
def wrapper():
func()
return wrapper
@A(1)
def func1():
print('装饰器')
func1() #我是参数 1
#装饰器
元类
元类被称为 Python 中的“深奥的巫术”。尽管你需要用到它的地方极少(除非你基于 zope 编程),可事实上它的基础理论其实令人惊讶地易懂。
一切皆对象
一切都有类型
“class”和“type”之间本质上并无不同
类也是对象
它们的类型是 type
就像对象是类的实例一样,类是它的元类的实例。
调用元类可以创建类。
确切来说,Python 中的其它对象也是如此。
因此当你创建一个类时……
解释器会调用元类来生成它……
定义一个继承自 object 的普通类意味着调用 type 来创建它:
type() ----> 用来构建所有类型的类
用法:
1.type(对象) ----》 返回的是对象的类型
2.type(name,bases,attrs) ----> name 类名 bases: tuple保存的是所有的父类 attrs:{} 字典 类中的所有的属性
所有的类底层都是经过type构建出来的。
print(type(int)) # <class 'type'>
class Student:
'''
这个是一个学生类
'''
type1 = '学生'
def __init__(self, name):
self.name = name
s = Student('tom')
print(Student.__dict__)
Student = type('Student', (object,), {'type1': '学生类'})
print(type(Student))
s = Student()
print(s)#<class 'type'>
#<__main__.Student object at 0x000001E0C3F61FD0>
print(Student.__dict__)#{'type1': '学生类', '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
单例类
单例(Singleton)
单例是一种 设计模式 ,应用该模式的类只会生成一个实例。
单例模式保证了在程序的不同位置都 可以且仅可以取到同一个对象实例
节省空间,节省资源,避免冲突
class Person:
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = object.__new__(cls, *args, **kwargs)
return cls.__instance
def __init__(self):
print('---->init')
p1 = Person()
p2 = Person()
p3 = Person()#三个引用的相同的地址
***********************
# 装饰器实现单例
class cls_decorator:
def __init__(self, f):
self.f = f
self.__instance = {}
def __call__(self, *args, **kwargs):
if self.f not in self.__instance:
self.__instance[self.f] = self.f() # self.f = Singleton Singleton()
return self.__instance[self.f] # {'Singleton':<Singleton object at 0x00000000022205F8>}
@cls_decorator # 1.cls = cls_decorator() 2. Singleton = cls
class Singleton:
def __init__(self):
print('---->Singleton init')
print(Singleton)
s1 = Singleton() # cls()
s2 = Singleton()#两次实例化对象相同
#<__main__.cls_decorator object at 0x0000017D63A717B8>
#---->Singleton init
print(s1 is s2) #True
抛出异常
异常:
try:
可能出现异常的代码
except:
如果存在异常执行的代码
else:
没有遇到异常执行的代码
finally:
无论是否存在异常都会执行的代码部分
如果代码有返回值+finally,则肯定会执行finally里面代码部分
在开发的时候,数据库连接,网络的连接,使用finally在最后的时候释放资源
两大部分:
- 处理异常: try…except
try…except…else 若except没有执行,即没有出错,就会执行else的内容
try…except…else…finally 若是try和finally里都有返回值,会返回finally里的,不再返回其他的 - 自定义异常 + raise
**********自定义异常*************
class UserNameError(Exception):
def __init__(self, *args, **kwargs):
pass
def register():
username = input('输入用户名:')
# 名字长度>=6,不能数字开头 '2'
if len(username) < 6 or username[0].isdigit():
# 用户名定义出错
raise UserNameError('用户名格式错误')
try:
register()
except Exception as err:
print(err)