python类的方法三种访问权_Python基础33-面向对象(继承资源(属性与方法)的使用注意)...

在Python中, 继承是指子类对父类资源的使用权

1 继承-属性与方法的使用权限

1.1 测试属性与方法分别如下

公有属性/方法

受保护属性/方法

私有属性/方法

class Animal:

a = 1 # 公有属性

_b = 2 # 受保护属性

__c = 3 # 私有属性

#公有方法

def t1(self):

print("t1")

# 受保护方法

def _t2(self):

print("t2")

# 私有方法

def __t3(self):

print("t3")

# 内置方法

def __init__(self):

print("init, Animal")

class Person(Animal):

# 在实例对象(子类)内对以上属性及方法的访问权限

def test(self):

print(id(self.a)) # 打印地址的目的是为了证明子类对父类属性继承是`可以使用`,而非`拥有副本`

print(self.a)

print(self._b)

# print(self.__c) # 不能访问私有属性

self.t1()

self._t2()

# self.__t3() # 不能访问私有方法

self.__init__()

p = Person()

p.test()

print(id(Animal.a))

p.test()

>>>> 打印结果

init, Animal

4502964848

1

2

t1

t2

init, Animal

4502964848

4502964848

1

2

t1

t2

init, Animal

除私有的属性和私有的方法, 其他属性和方法子类基本都能继承(具有使用权)

2 继承-通过子类给父类属性进行赋值时,默认是指给之类增加一个与父类同名的属性

class Father:

age = 10

class Son(Father):

pass

print(Son.age) # 访问父类属性

Son.age = 9 # 给子类增加与父类同名属性

print(Son.age)

print(Father.age)

print(Son.__dict__)

print(Father.__dict__)

>>>>打印结果

10

9

10

{'__module__': '__main__', '__doc__': None, 'age': 9}

{'__module__': '__main__', 'age': 10, '__dict__': , '__weakref__': , '__doc__': None}

3 继承的3种形态

继承的3种形态

4 几种形态应该遵循的标准原则

4.1 单继承

遵循"从下到上的原则"

自己身上没有这个资源, 就到父类里面去找,父类里面没有再往上找

4.2 无重叠的多继承

遵循"单调原则"

按照继承的先后顺序,优先调用左侧继承链上的资源

4.3 有重叠的多继承

遵循"从下到上的原则"

简单理解就是:

A继承B继承C

B重写了C类的方法, 那么A优先使用B类的方法

4 查看类的资源查找顺序方法

通过inspect模块进行

目的:假如继承链中多个父类重写的资源,要学会查找哪些类的重写资源会被优先调用

# 导入资源查看模块 inspect

import inspect

class D(object):

pass

class B(D):

pass

class C(D):

pass

class A(B, C):

pass

# 方法一

print(inspect.getmro(A))

# 方法二

print(A.__mro__)

# 方法三

print(A.mro())

>>>>打印结果

(, , , , )

(, , , , )

[, , , , ]

TODO:《 针对于几种标准原则的方案演化》

不同 Python 版本 MRO 原则

菱形继承链问题

5 资源覆盖(MRO 优先级高的优先调用)

5.1 原理

基于MRO的资源检索链

优先级高的类具有一个与优先级低的类一样的一个资源(属性或方法)

会先选择优先级高的资源 ,而摒弃优先级低的资源(造成"覆盖"的假象)

class D(object):

age = "d"

pass

class C(D):

age = "c"

def test(self):

print("c")

pass

class B(D):

# age = "b"

def test(self):

print("b")

pass

class A(B, C):

pass

a = A()

a.test()

print(A.mro())

print(A.age)

print(A().test())

>>>>打印结果

b

[, , , , ]

c

b

None

5.2 调用优先级高资源时,self 与 cls 的变化

结论:谁调用,就是谁

class D(object):

pass

class C(D):

def test(self):

print(self)

pass

class B(D):

def test(self):

print(self)

@classmethod

def test2(cls):

print(cls)

pass

class A(B, C):

pass

A.test2()

a = A()

a.test()

>>>>打印结果

6 在低优先级类的方法中,通过"super"调用高优先级类的方法

Python3.x

class B:

a = 1

def __init__(self):

self.b = 2

self.xxx = "123"

def t1(self):

print("t1")

@classmethod

def t2(cls):

print(cls)

print("t2")

@staticmethod

def t3():

print("t3")

class A(B):

c = 3

def __init__(self):

super().__init__()

self.e = "666"

def tt1(self):

print("tt1")

@classmethod

def tt2(cls):

super().t2()

print("tt2")

@staticmethod

def tt3():

print("tt3")

pass

a = A()

print(a.__dict__)

print("-" * 20)

A.tt2()

>>>>打印结果

{'b': 2, 'xxx': '123', 'e': '666'}

--------------------

t2

tt2

Python2.2+

class B:

a = 1

def __init__(self):

self.b = 2

self.xxx = "123"

def t1(self):

print("t1")

@classmethod

def t2(cls):

print(cls)

print("t2")

@staticmethod

def t3():

print("t3")

class A(B):

c = 3

def __init__(self):

super(A, self).__init__()

self.e = "666"

def tt1(self):

print("tt1")

@classmethod

def tt2(cls):

super(A, cls).t2()

print("tt2")

@staticmethod

def tt3():

print("tt3")

pass

a = A()

print(a.__dict__)

print("-" * 20)

A.tt2()

>>>>打印结果

{'b': 2, 'xxx': '123', 'e': '666'}

--------------------

t2

tt2

注意

super 和父类(超类)没有实质性的关联

仅仅是沿着MRO链条, 找到下一级节点

保证调用形式的统一

要是类名调用, 全是类名调用

要是super调用, 全是super调用

(混合使用容易出现死循环)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值