python学习笔记十六

多重继承

什么是多重继承

继承是面向对象编程的一个重要的方式,通过继承,子类就可以扩展父类的功能。在python中一个类能继承自不止一个父类,这叫做多重继。
优点:继承前面类的功能,达到扩展现有类的功能。
注意:多重继承,一定要理清执行顺序,避免程序混乱,建议一般不用多重继承。

class A:
    def m(self):
        print("我是 A") 
class B(A):
    def m(self):
        print("我是 B")
        A.m(self)
class C(A):
    def m(self):
        print("我是 C")
        A.m(self)
class D(B, C):
    def m(self):
        print("我是 D") 
B.m(2)
C.m(3)

bases 获取当前类继承的父类

print(C.bases)

super() 避免被调用父类多次初始化

super()是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

class A(object):
    def __init__(self):
        print ("我是 A")
class B(A):
    def __init__(self):
        print("我是 B")
        super(B, self).__init__()
class C(A):
    def __init__(self):
        print("我是 C")
        super(C, self).__init__()
class D(B, C):
    def __init__(self):
        print ("我是 D")
        super(D, self).__init__()
class E(A):
    def __init__(self):
        print ("我是 E")
        super(E, self).__init__()
class F(D, E):
    def __init__(self):
        print ("我是 F")
        super(F, self).__init__()
F = F()

多态

多态是指一类事物有多种形态,比如动物类,可以有猫,狗,猪等等。(一个抽象类有多个子类,因而多态的概念依赖于继承)

多态性

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。

class Cat(): #动物的形态之一:猫
    def talk(self):
        print('喵喵叫'')
class Dog(): #动物的形态之二:狗
    def talk(self):
        print('汪汪叫')
class Pig(): #动物的形态之三:猪
    def talk(self):
        print('嗷嗷叫'')
c = Cat()
d = Dog()
p = Pig()
def func(obj):
    obj.talk()
func(c)
func(d)
func(p)

多态性的好处:

1、增加了程序的灵活性,以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(obj)
2、增加了程序额可扩展性,,使用者无需更改自己的代码,还是用func(obj)去调用

鸭子类型

一个函数可以接受一个任意类型的对象,并调用它的"走"和"叫"方法。任何拥有这样的正确的"走"和"叫"方法的对象都可被函数接受的这种行为就是鸭子类型。
类的属性:一般分为公有属性和私有属性,默认情况下所有得属性都是公有的,如果属性的名字以两个下划线开始,就表示为私有属性,没有下划线开始的表示公有属性。 python的属性分为实例属性和静态属性,实例属性是以self为前缀的属性,如果构造函数中定义的属性没有使用self作为前缀声明,则该变量只是普通的局部变量,类中其它方法定义的变量也只是局部变量,而非类的实例属性。

属性和方法

  • 实例属性
  • 类属性
  • 实例方法
  • 类方法
  • 静态方法
    1、类的定义

例子:
class User():
pass
说明:
(1)定义了一个类名为User的类
(2)类名一般约定用大写字母开头,函数则用小写字母开头,以做区分
(3)用pass表示为空类,暂时还没准备好类的内容
2、类的方法
例子:
class User():
def say(self) -> None:
print(‘hello’)
调用:
a = User()
a.say()
print(hex(id(a)))
print(a)
运行结果:
hello
0x36dfd68
<main.User object at 0x00000000036DFD68>
说明:
(1)上面定义了方法say,方法可以有0到多个参数,但第一个参数是必须有的,第一个参数有约定俗成的名字叫self在对象上调用一个方法时,不需要手动为self提供一个值,原因是解释器会自动把调用对象实例做为第一个参数,赋值给各个方法的self参数。
例如上面a.say()不需要为self提供值,解释器会自动转换为User.say(a)
(2)self 代表的是类的实例,上面hex(id(a))查询实例的内存地址,可以看出和打印对象名是同个地址。
对象可以用__repr__方法覆盖,例子:
class User():
def repr(self) -> str:
return ‘覆盖默认行为’
调用:
a = User()
print(a)
运行结果:
覆盖默认行为
3、类的属性
例子:
class User():
def init(self, name: str) -> None:
self.name = name
def say(self) -> str:
print(‘我的名字是:’, self.name)
调用:
a = User(‘张三’)
print(a.name)
a.say()
运行结果:
张三
我的名字是: 张三

异常

在编写程序时,难免会遇到错误,有的是编写人员疏忽造成的语法错误,有的是程序内部隐含逻辑问题造成的数据错误,还有的是程序运行时与系统的规则冲突造成的系统错误,等等。总的来说,编写程序时遇到的错误可大致分为 2 类,分别为语法错误和运行时错误。
try语句
try:
代码块(可能出现错误的语句)
except 异常类型 as 异常名:
代码块(出错错误之后处理的方式)
except 异常类型 as 异常名:
代码块(出错错误之后处理的方式)
except 异常类型 as 异常名:
代码块(出错错误之后处理的方式)

else:
代码块(没有出错时要执行的语句)
finally:
代码块(该代码块总会执行)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值