Python面向对象编程04:类继承和其衍生术语Pytho

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

正式的Python专栏第39篇,同学站住,别错过这个从0开始的文章!

前篇学委展示分享了类的继承和重写,面向对象还有一些概念,继续跟上吧!

Python Override

Override还能重写类的一些通用函数,它们是:

  • __init__
  • __str__
  • __eq__

这里手动写几个,因为我们双击object这个base class可以看到一系例的类的函数:

屏幕快照 2021-11-18 下午11.45.02.png

学委准备了下面的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/15 11:58 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : __init__.py.py
# @Project : hello
"""
下面是一个程序员类定义
"""


class Programmer(object):
    def __init__(self, name):
        self.name = name

    def code(self):
        print(f"{self.name}: life is short, why not python?")


p = Programmer("学委粉丝")
# p.code() #TypeError: code() missing 1 required positional argument: 'lang'
p.code()
print("p:", p)
print("namespace:", Programmer.__dict__)


class JavaProgrammer(object):
    def __init__(self, name):
        self.name = name

    def code(self):
        print(f"{self.name}: like if like a box of chocolate?")

    def __str__(self):
        return f"JavaProgrammer(name:{self.name})"


p = JavaProgrammer("学委粉丝2号")
# p.code() #TypeError: code() missing 1 required positional argument: 'lang'
p.code()
print("p:", p)
复制代码

这是运行结果:

屏幕快照 2021-11-18 下午11.41.33.png

我们下面在上面的代码基础上重写__eq__ 函数。

重写 == 操作:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/15 11:58 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : __init__.py.py
# @Project : hello
"""
下面是一个程序员类定义
"""


class JavaProgrammer(object):
    def __init__(self, name):
        self.name = name

    def code(self):
        print(f"{self.name}: like if like a box of chocolate?")

    def __str__(self):
        return f"JavaProgrammer(name:{self.name})"

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.name == other.name
        return False


p1 = JavaProgrammer("学委粉丝2号")
# p.code() #TypeError: code() missing 1 required positional argument: 'lang'
p1.code()
print("p1:", p1)

p2 = JavaProgrammer("学委粉丝2号")
# p.code() #TypeError: code() missing 1 required positional argument: 'lang'
p2.code()
print("p2:", p2)
print("same ? ", p1 == p2)
复制代码

重写之后两个对象果然相等了!(可能初学者会觉得有点奇怪,name不是一样吗)

在Python中两个对象属性都相同,但是它们不一定相等的。

屏幕快照 2021-11-19 上午12.45.58.png

这是注释了eq函数后到运行结果:

屏幕快照 2021-11-19 上午12.43.38.png

Python 默认不支持方法重载!

什么是重载?

重载这种行为就是一个类出现多个同名函数,必然的函数接收的参数不一样(一样不久重复定义了,像Java直接就报错了!)

这在Python中默认不支持的。

我们看看下面的代码,学委写了两个同名函数code但是参数数量稍微区别开了:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/15 11:58 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : __init__.py.py
# @Project : hello
"""
下面是一个程序员类定义
"""


class Programmer(object):
    def __init__(self, name):
        self.name = name

    def code(self):
        print(f"{self.name}: life is short, why not python?")

    def code(self, lang):
        print(f"{self.name}: life is short, why not {lang} ?")




p = Programmer("学委粉丝")
#下面的代码取消注释会报错
#p.code() #TypeError: code() missing 1 required positional argument: 'lang'
p.code("java")
print("namespace:", Programmer.__dict__)
复制代码

运行结果如下:

屏幕快照 2021-11-19 上午8.49.08.png

这里我把运行结果的namespace复制出来了:

namespace: {'__module__': '__main__', '__init__': <function Programmer.__init__ at 0x1042ad280>, 'code': <function Programmer.code at 0x104494d30>, '__dict__': <attribute '__dict__' of 'Programmer' objects>, '__weakref__': <attribute '_weakref_' of 'Programmer' objects>, '__doc__': None}

我们看到namespace里面只有一个code,这告诉我们在内存中,python这个类值映射到一个code函数,明显是后者(第二个code函数)。

但是有库可以做到重载,后面继续说。

总结

读者还可以选取一些object的函数进行重写试试。

类继承带来便利的同时,也带来了复杂度。

因为有时候子类调用父类完成一部分工作,父类调用其他,这样反反复复,整个函数处理逻辑就非常难以一目了然看明白,只能通过看局部代码跳来跳去的拼凑成一个接近全貌的认识。

好处就是重复做的代码少了,组件更加简洁。

学委写了十几年的Java了,但是写的这套Python教程非常务实,对基础编程有任何问题请查看相关文章。

喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏

持续学习持续开发,我是雷学委!
编程很有趣,关键是把技术搞透彻讲明白。
欢迎关注微信,点赞支持收藏!