Python核心技术与实战
景霄
Facebook资深工程师
立即订阅
13891 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 从工程的角度深入理解Python
免费
基础篇 (14讲)
01 | 如何逐步突破,成为Python高手?
02 | Jupyter Notebook为什么是现代Python的必学技术?
03 | 列表和元组,到底用哪一个?
04 | 字典、集合,你真的了解吗?
05 | 深入浅出字符串
06 | Python “黑箱”:输入与输出
07 | 修炼基本功:条件与循环
08 | 异常处理:如何提高程序的稳定性?
09 | 不可或缺的自定义函数
10 | 简约不简单的匿名函数
11 | 面向对象(上):从生活中的类比说起
12 | 面向对象(下):如何实现一个搜索引擎?
13 | 搭建积木:Python 模块化
14 | 答疑(一):列表和元组的内部实现是怎样的?
进阶篇 (11讲)
15 | Python对象的比较、拷贝
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
17 | 强大的装饰器
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
19 | 深入理解迭代器和生成器
20 | 揭秘 Python 协程
21 | Python并发编程之Futures
22 | 并发编程之Asyncio
23 | 你真的懂Python GIL(全局解释器锁)吗?
24 | 带你解析 Python 垃圾回收机制
25 | 答疑(二):GIL与多线程是什么关系呢?
规范篇 (7讲)
26 | 活都来不及干了,还有空注意代码风格?!
27 | 学会合理分解代码,提高代码可读性
28 | 如何合理利用assert?
29 | 巧用上下文管理器和With语句精简代码
30 | 真的有必要写单元测试吗?
31 | pdb & cProfile:调试和性能分析的法宝
32 | 答疑(三):如何选择合适的异常处理方式?
量化交易实战篇 (8讲)
33 | 带你初探量化世界
免费
34 | RESTful & Socket: 搭建交易执行层核心
35 | RESTful & Socket: 行情数据对接和抓取
36 | Pandas & Numpy: 策略与回测系统
免费
37 | Kafka & ZMQ:自动化交易流水线
38 | MySQL:日志和数据存储系统
39 | Django:搭建监控平台
40 | 总结:Python中的数据结构与算法全景
技术见闻与分享 (4讲)
41 | 硅谷一线互联网公司的工作体验
42 | 细数技术研发的注意事项
加餐 | 带你上手SWIG:一份清晰好用的SWIG编程实践指南
43 | Q&A:聊一聊职业发展和选择
结束语 (1讲)
结束语 | 技术之外的几点成长建议
Python核心技术与实战
登录|注册

11 | 面向对象(上):从生活中的类比说起

景霄 2019-06-03
你好,我是景霄。
很多朋友最开始学编程的时候,是从 C++ 或者 JAVA 语言入手的。他们好不容易磕磕绊绊地搞懂了最基本的数据类型、赋值判断和循环,却又迎面撞上了 OOP (object oriented programming) 的大墙,一头扎进公有私有保护、多重继承、多态派生、纯函数、抽象类、友元函数等一堆专有名词的汪洋大海中找不到彼岸,于是就放弃了进阶之路。
相比之下,Python 是一门相对友好的语言,它在创立之初就鼓励命令交互式的轻量级编程。理论上,Python 的命令式语言是图灵完备的, 也就是说命令式语言,理论上可以做到其他任何语言能够做到的所有的事情,甚至进一步,仅仅依靠汇编语言的 MOV 指令,就能实现图灵完备编程
那么为什么不这样做呢?其实,“上古时代”的程序员就是这么做的,可是随着程序功能复杂性的逐步提升,以及需求的不断迭代,很多老旧的代码修改起来麻烦无比,牵一发而动全身,根本无法迭代和维护,甚至只能推倒重来,这也是很多古老的代码被称为“屎山”的原因。
传统的命令式语言有无数重复性代码,虽然函数的诞生减缓了许多重复性,但随着计算机的发展,只有函数依然不够,需要把更加抽象的概念引入计算机才能缓解(而不是解决)这个问题,于是 OOP 应运而生。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Python核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(76)

  • Jingxiao 置顶
    思考题答案:庄小P 同学的写法很好,非常明确的表明了菱形继承潜在的问题:一个基类的初始化函数可能被调用两次。在一般的工程中,这显然不是我们所希望的。正确的做法应该是使用 super 来召唤父类的构造函数,而且 python 使用一种叫做方法解析顺序的算法(具体实现算法叫做 C3),来保证一个类只会被初始化一次。

    class A():
        def __init__(self):
            print('enter A')
            print('leave A')

    class B(A):
        def __init__(self):
            print('enter B')
            super().__init__()
            print('leave B')

    class C(A):
        def __init__(self):
            print('enter C')
            super().__init__()
            print('leave C')

    class D(B, C):
        def __init__(self):
            print('enter D')
            super().__init__()
            print('leave D')

    D()

    enter D
    enter B
    enter C
    enter A
    leave A
    leave C
    leave B
    leave D
    2019-06-04
    59
  • hlz-123
    第一个问题,面向对象编程四要素是什么?它们的关系又是什么?
    答:面向对象编程四要素是类,属性,函数,对象,
           它们关系可以总结为:类是一群具有相同属性和函数的对象的集合。
    第二个问题,讲了这么久的继承,继承究竟是什么呢?你能用三个字表达出来吗?
    三个字:父与子。儿子可以使用自己的东西,没有的可以使用父亲的东西。
    2019-06-03
    46
  • 庄小P
    class A():
        def __init__(self):
            print('A class called')

    class B(A):
        def __init__(self):
            print('B class called')
            A.__init__(self)
    class C(A):
        def __init__(self):
            print('C class called')
            A.__init__(self)
    class D(B,C):
        def __init__(self):
            print('D class called')
            B.__init__(self)
            C.__init__(self)
    d = D()
    ####输出
    D class called
    B class called
    A class called
    C class called
    A class called
    2019-06-03
    35
  • helloworld
    面向对象编程的四要素: 类、属性、函数(方法)、对象(实例)

    下面来展开总结:

    类: 一群有着相同属性和函数(方法)的对象(实例)的集合,也可以具象化的理解为是一群有着相似特征的事物的集合;用class来声明。
    抽象类:是一种特殊的类,只能作为父类存在,一旦对象化(或叫实例化)就会报错;一般使用class Classname(metaclass=ABCMeta)来声明。
    类的继承:子类继承父类,子类可以使用父类的属性和函数,同时子类可以有自己独特的属性和函数;子类在生成对象的时候(实例化时),是不会自动调用父类的构造函数的,必须在子类的构造函数中显示的调用父类的构造函数;继承的优势是减少重复代码,降低系统熵值(即复杂度)。

    属性:用"self.属性名"来表示,通过构造函数传入;表示对象(实例)的某个静态特征。
    私有属性:以__开头的属性,举例:self.__属性名,只能在类内部调用,类外部无法访问。
    公有属性:和函数并列声明的属性,可以理解为常量,一般用全大写表示;在类中通过"self.常量名"来调用,在类外使用"对象名.常量名"或者"类名.常量名"来调用。

    函数:表示对象(实例)的某个动态能力。
    构造函数:用def __init__(self, args...)声明,第一个参数self代表当前对象的引用,其他参数是在对象化时需要传入的属性值;构造函数在一个对象生成时(即实例化时)会被自动调用。
    成员函数:是正常的类的函数,第一个参数必须是self;可通过此函数来实现查询或修改类的属性等功能。
    静态函数:静态函数和类没有什么关联,第一个参数也没有什么特殊性;一般用来做一些简单独立的任务,既方便测试也能优化代码结构;一般使用装饰器@staticmethod来声明。
    类函数:类函数的第一个参数一般为cls,表示必须传一个类进来;最常用的功能是实现不同的init构造函数;需要装饰器@classmethod来声明。
    抽象函数:一般定义在抽象类中,主要目的是要求子类必须重载该函数才能正常使用;使用装饰器@abstractmethod来声明。
    函数重载:父类的某函数通过raise Exception的方式要求子类必须重写该函数来覆盖父类原有函数。

    对象:类对象化(实例化)后的某一个具体事物。
    2019-06-04
    5
    24
  • 不瘦到140不改名
    思考题:多重继承,是基于mro进行查找,使用的是一种C3的算法。总结一下规律就是:
    B F

    C G

    D H

    E I

      J
    在python3中,如果最顶层的两个类没有继承共同的类,那么查找顺序是,先从左找到头,再从右找到头,即,J->E->D->C->B->I->H->G->F

      A
    B F

    C G

    D H

    E I

      J
    如果继承了共同的类,也就是形成了菱形结构,那么查找顺序为,先从左找,只找到倒数第二层,然后从右找到头,即J->E->D->C->B->I->H->G->F->A
    2019-06-03
    20
  • 奔跑的蜗牛
    经典类:深度优先,F->D->B->A->E->C->H
    新式类:广度优先,F->D->B->E->C->H->A

    class A:
        # def test(self):
        # print('from A')
        pass
    class B(A):
        # def test(self):
        # print('from B')
        pass
    class C(A):
        # def test(self):
        # print('from C')
        pass

    class D(B):
        # def test(self):
        # print('from D')
        pass

    class E(C):
        # def test(self):
        # print('from E')
        pass

    class H(A):
        def test(self):
            print('from H')
        pass
    class F(D,E,H):
        # def test(self):
        # print('from F')
        pass
    f=F()
    f.test()
    print(F.mro())

    作者回复: 👍

    2019-06-03
    11
  • LiANGZE
    只知道多重继承时会通过mro算法生成一个顺序,可以通过 xxx.__mro__ 查看继承的顺序,但其中原理确实没深入研究过 🤔
    2019-06-03
    10
  • Geek_59f23e
    哥,能不能教教怎么搭梯子?给的链接都是国外的,进不了咋整。。
    2019-06-04
    1
    8
  • DX3906
    init双下方法是初始化方法,构造方法是双下new
    2019-06-03
    5
  • 清风
    我到底该叫方法还是叫函数
    2019-06-09
    3
  • Fergus
    先写答案再看答案:
    Q1.面向对象编程四要素是什么?它们的关系又是什么?

    A. 类,实例(对象),属性,方法(函数);

    一般情况下,使用类前需要先实例化,即创建对象;属性是类实例化时由构造函数\_\_init__定义完成,表示类的静态特性,方法是类获取/修改类的属性的动作,表示类的动态能力;



    Q2.继承究竟是什么?

    A. “拿来用”

    Q3.菱形继承,BC 继承了 A,然后 D 继承了 BC,创造一个D 的对象。那么,构造函数调用顺序又是怎样的呢?

    A.

    ```
    class A():
        pass

    class B(A):
        pass

    class C(A):
        pass

    class D(B, C):
        pass

    d = D()
    ```

    2019-06-03
    3
  • Geek_00bd9e
    作者您好,引用您的例子,我想问个问题,执行到enter B的时候为什么没有输出enter A,B类不是继承了A类了吗? 反而输出enter C,然后才输出enter A。这个地方比较疑惑?
    class A():
        def __init__(self):
            print('enter A')
            print('leave A')

    class B(A):
        def __init__(self):
            print('enter B')
            super().__init__()
            print('leave B')

    class C(A):
        def __init__(self):
            print('enter C')
            super().__init__()
            print('leave C')

    class D(B, C):
        def __init__(self):
            print('enter D')
            super().__init__()
            print('leave D')

    D()

    enter D
    enter B
    enter C
    enter A
    leave A
    leave C
    leave B
    leave D
    2019-06-06
    3
    2
  • Fergus
    感谢老师对答案的补充,回头复习看到答案又增加了新知。
    2019-06-05
    2
  • 程序员人生
    类函数有什么特别之处?
    2019-06-03
    2
  • GLADIATOR
    老师,我有一个疑问:从C++和java来看,构造函数肯定是先执行父类再构造子类,根据您的例子只是把print放在了父类构造函数之前,所以看起来单继承是先子后父,单实际上通过调试可以看出,其实仍然是先父后子。
    2019-06-12
    1
    1
  • 爬行的蜗牛
    1. 面向对象编程的四要素是什么, 它们的关系是什么
    - 抽象
    - 封装
    - 继承
    - 多态
    个人理解:
    -抽象的本质是抽取不同类的的相同方法(函数)和属性, 作为父类的属性和方法;
    - 封装就是把功能封装抽象的方法和其他属性和方法;
    - 子类继承父类的抽象出来的属性和方法;
    - 多态就是重写抽象的方法(函数)。

    2. 继承是什么? 用三个字表示出来;
    子类继承父类的属性和方法(函数)减少代码量和复杂度;
    三个字:承接:属性&函数

    作者回复: 👍

    2019-06-07
    1
  • Geek_59f23e
    1. 类 对象 属性 函数
    2. DRY (don't repeat yourself)
    3. D B A C (C3算法)
    2019-06-04
    1
  • lllong33
    1、面向对象的四要素,关系?
    - 类、对象,属性,函数
    - 类是一群具有相同属性和函数的对象的集合。

    2、用三个词描述继承
    - 重构、多态、复用性

    3、多重继承,函数执行顺序
    - 遵循MRO(method resolution order)原则,从左至右使用顺序。
    参考:[调用父类方法](https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html)
    2019-06-04
    1
  • Fergus
    对于思考题,感谢提到c3算法的小伙伴,给补充了知识。但可能过度解读老师的意图了吧
    2019-06-03
    1
  • kevinsu
    第一题
    由类,属性,函数,对象联想到了哺乳动物这块儿例如猴子和人,人的特征属性和行为,猴子的特征属性和行为,以及根据物种起源学说我们可能有共同的老祖先且继承了老祖先的一些属性和函数。这样来理解这几个概念非常深刻。
    第二题
    父与子,不管是不是富二代,儿子都从父亲那里继承很多属性和函数。
    2019-06-03
    1
收起评论
76
返回
顶部