写点什么

Python OOP-3

用户头像
若尘
关注
发布于: 2021 年 04 月 26 日
Python  OOP-3

## 6.3 多态

- 多态就是同一个对象在不同情况下有不同的状态出现

- 多态不是语法,是一种设计思想

- 多态性:一种调用方式,不同的执行效果

- 多态:同一事物的多种形态,动物分为人类、猪类、狗类

- [多态和多态性](https://www.cnblogs.com/luchuangao/p/6739557.html)

- Mixin 设计模式

- 主要采用多继承方式对类的功能进行扩展

- [Mixin 概念](https://www.zhihu.com/question/20778853)

- [MRO and Mixin](http://blog.csdn.net/robinjwong/article/details/48375833)

- [Mixin 模式](https://www.cnblogs.com/xybaby/p/6484262.html)

- [Mixin MRO](http://runforever.github.io/2014-07-19/2014-07-19-python-mixin%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/)

- [MRO](http://xiaocong.github.io/blog/2012/06/13/python-mixin-and-mro/)

- 我们使用多继承语法来实现 Mixin

- 使用 Mixin 实现多继承的时候非常小心

- 首先他必须表示某一单一功能,而不是某个物品

- 职责必须单一,如果有多个功能,则写多个 Mixin

- Mixin 不能依赖于子类的实现

- 子类即使没有继承这个 Mixin 类,也能照样工作,只是缺少了某个功能

- 优点

- 使用 Mixin 可以在不对类进行任何修改的情况下,扩充功能

- 可以方便的组织和维护不同功能组件的划分

- 可以根据需要任意调整功能类的组合

- 可以避免创建很多新的类,导致类的继承混乱

# 7. 类相关函数

- issubclass:检测一个类是否是另一个类的子类

- isinstance:检测一个对象是否是一个类的实例

- hasattr:检测一个对象是否有成员 xxx

- getattr:get attribute

- setattr:set attribute

- delattr:delete attribute

- dir:获取对象的成员列表

```python

class A():

pass

class B(A):

pass

class C(B,A):

pass

print(A.__mro__)

print(B.__mro__)

```

(<class '__main__.A'>, <class 'object'>)

(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

```python

# 多继承的例子

# 子类可以直接拥有父类的属性和方法,私有属性和方法除外

class Fish():

def __init__(self, name):

self.name = name

def swim(self):

print("I am swimming......")

class Bird():

def __init__(self, name):

self.name = name

def fly(self):

print("I am flying.....")

class Person():

def __init__(self, name):

self.name = name

def worked(self):

print("Working......")

class SuperMan(Person, Bird, Fish):

def __init__(self, name):

self.name = name

s = SuperMan("a")

s.fly()

s.swim()

s.worked()

# 单继承的例子

class Student(Person):

def __init__(self, name):

self.name = name

stu = Student("a")

stu.worked()

```

I am flying.....

I am swimming......

Working......

Working......

```python

# 菱形继承问题

class A():

pass

class B(A):

pass

class C(A):

pass

class D(B,C):

pass

```

```python

# 构造函数例子

class Person():

# 对 Person 类进行实例化的时候

# 姓名要确定

# 年龄得确定

# 地址肯定有

def __init__(self):

self.name = "NoName"

self.age = 18

self.address = "Studentwhonheim"

print("In init func")

# 实例化一个人

p = Person()

```

In init func

```python

# 构造函数的调用顺序 - 1

# 如果子类没有写构造函数,则自动向上查找,直到找到为止

class A():

def __init__(self):

print("A")

class B(A):

def __init__(self):

print("B")

class C(B):

pass

# 此时,首先 C 的构造函数

# 如果没有,则向上按照 MRO 顺序查找父类的构造函数,直到找到为止

c = C()

```

A

```python

# 构造函数的调用顺序 - 2

class A():

def __init__(self):

print("A")

class B(A):

def __init__(self, name):

print("B")

print(name)

class C(B):

pass

# 此时,首先 C 的构造函数

# 如果没有,则向上按照 MRO 顺序查找父类的构造函数,直到找到为止

# 此时,会出现参数结构不对应错误

c = C()

```

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

TypeError Traceback (most recent call last)

<ipython-input-11-40c74f7fff64> in <module>

14 # 如果没有,则向上按照 MRO 顺序查找父类的构造函数,直到找到为止

15 # 此时,会出现参数结构不对应错误

---> 16 c = C()

TypeError: __init__() missing 1 required positional argument: 'name'

```python

# 构造函数的调用顺序 - 3

class A():

def __init__(self):

print("A")

class B(A):

def __init__(self, name):

print("B")

print(name)

class C(B):

# C 中想扩展 B 的构造函数

# 即调用 B 的构造函数后再添加一些功能

# 有两种方法实现

'''

# 第一种是通过父类名调用

def __init__(self, name):

# 首先调用父类构造函数

B.__init__(self, name)

# 其次,再增加自己的功能

print("这是 C 中附加的功能")

'''

# 第二种,使用 super 调用

def __init__(self, name):

# 首先调用父类构造函数

super(C, self).__init__(name)

# 其次,再增加自己的功能

print("这是 C 中附加的功能")

# 此时,首先 C 的构造函数

# 如果没有,则向上按照 MRO 顺序查找父类的构造函数,直到找到为止

# 此时,会出现参数结构不对应错误

c = C("我是 C")

```

B

我是 C

这是 C 中附加的功能

```python

# Mixin 案例

class Person():

name = "ruochen"

age = 18

def eat(self):

print("EAT......")

def drink(self):

print("DRINK......")

def sleep():

print("SLEEP......")

class Teacher(Person):

def work(self):

print("Work")

class Student(Person):

def study(self):

print("Study")

class Tutor(Teacher, Student):

pass

t = Tutor()

print(Tutor.__mro__)

print(t.__dict__)

print(Tutor.__dict__)

print("*" * 20)

class TeacherMixin():

def work(self):

print("Work")

class StudentMixin():

def study(self):

print("Study")

class TutorM(Person, TeacherMixin, StudentMixin):

pass

tt = TutorM()

print(TutorM.__mro__)

print(tt.__dict__)

print(TutorM.__dict__)

```

(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)

{}

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

********************

(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)

{}

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

```python

# issubclass

class A():

pass

class B(A):

pass

class C():

pass

print(issubclass(B, A))

print(issubclass(C, A))

print(issubclass(C, object))

```

True

False

True

```python

# isinstance

class A():

pass

a = A()

print(isinstance(a, A))

print(isinstance(A, A))

```

True

False

```python

# hasattr

class A():

name = "NoName"

a = A()

print(hasattr(a, "name"))

print(hasattr(a, "age"))

```

True

False

```python

# help 案例

# 我想知道 setattr 的具体用法

help(setattr)

```

Help on built-in function setattr in module builtins:

setattr(obj, name, value, /)

Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''

```python

# dir 案例

class A():

pass

# dir(A)

a = A

dir(a)

```

['__class__',

'__delattr__',

'__dict__',

'__dir__',

'__doc__',

'__eq__',

'__format__',

'__ge__',

'__getattribute__',

'__gt__',

'__hash__',

'__init__',

'__init_subclass__',

'__le__',

'__lt__',

'__module__',

'__ne__',

'__new__',

'__reduce__',

'__reduce_ex__',

'__repr__',

'__setattr__',

'__sizeof__',

'__str__',

'__subclasshook__',

'__weakref__']

发布于: 2021 年 04 月 26 日阅读数: 10
用户头像

若尘

关注

还未添加个人签名 2021.01.11 加入

还未添加个人简介

评论

发布
暂无评论
Python  OOP-3