Python官方教程阅读总结-类(Class)

类定义了一种数据类型,把数据和函数绑定在一起,创建一个新的类就创建了一个新的对象类型


方法和函数的简要区分

这里讲到类的时候,对函数和方法这两个称谓做一下区分,在类中定义的函数,我们一般称为该类的方法。两者的区别不是特别大(主要是类的对象在调用方法的时候的参数self问题),刚开始学也不用特意去区分。

1. 名称和对象

对象具有个体性, 多个名称可以绑定到同一个对象中,这在其他语言中被称为别名,在涉及到可变象的时候比较有用。

2. 作用域和命名空间

    2.1 作用域是名称到对象的映射,在python中通常是用字典类型来实现。命名空间的例子:内置的名称,模块中的全局名称,函数调用过程中的局部名称。在某种程度上,一个对象的属性也构成了一个命名空间。

    2.2 不同命名空间之间绝对没有联系,例如,不同的模块中可能都包含max函数,但是却不会引起冲突,这是因为他们属于不同的命名空间。调用的时候用 模块名.函数名()来调用,这也是前面讲的避免名称冲突的方法

    2.3 通过点(.)调用的名称称为属性,如 student.name, 其中 student 是一个对象,name是这个对象的属性。在模块中,引用名称就是属性的引用。

    2.4 属性是只读或者可写的,在可写状态下,属性可以赋值,也可以删除,如:

        student.name = "Bill"

        del student.name

    2.5 命名空间可在不同的时刻创立,并且有不同的寿命。例如:

            python内置名称所在的命名空间在解释器启动时候创立,不会被删除

            模块的全局命名空间在解释器读取模块的时候创立,在解释器退出的时候删除

            python执行的脚本或者语句属于__main__模块,有自己的命名空间

            一个函数的局部命名空间在该函数被调用的时候创立,函数返回或报错时删除(函数回归调用时的每一层有自己的一个命名空间)

    2.6 作用域是指能直接触到命名空间的区域,作用域动态得发挥作用,在程序执行过程中,至少有三种嵌套作用域,他们的命名空间是可以直接接触到的:

            最内层的作用域:包含局部名称,这是最先被查找的

            闭合函数的作用域:包含non-local, non-global

            倒数每二层的作用域:当前模块下的全局名称

            最外层作用域:内置名称(built-in names)所在的作用域,最后被查找

        通常,局部作用域引用当前函数的局部名称,在函数外,局部作用域和全局作用域都引用同一个命名空间,都是当前模块的命名空间。定义类的时候引入的是另一个局部作用域

        定义到模块内部的函数的全局作用域就是指该模块的命名空间

        如果没有 global 关键字声明,一个名称的赋值操作总是跑到最内层的作用域,赋值操作不会复制数据,只是把名称和对象(数据)绑定起来。del作用正好相反,把这种绑定解除

        所有引入新名称的操作,都使用局部作用域。例如,import 模块和函数定义就会把模块和函数绑定到local作用域中

        global声明的作用:声明该变量存在于全局作用域中,应该反应到全局作用域中

        non-local 声明的作用: 声明该变量存在于一个闭合作用域,应该反应到这个闭合作用域中

    例子:

            在上面这个例子中,do_local()作用的是最内层的局部命名空间,do_nonlocal()作用在scope_test() 所在的命名空间,do_global()作用的是模块(__main__)的命名空间。

3. 定义类

    3.1 关键字 class 来定义类,后面跟类名,然后在类中进行属性的和方法的定义,格式如下:

            类的定义多是类中方法的定义

    3.2 类的对象

        类的对象支持两种操作:对象引用和实例化操作(以上例进行说明)

        对象引用:testClass.name

        实例化:test = testClass() 

                      test.name

        上面的实例化过程其实是默认调用了类的无参构造函数来实例化,用户也可以通过__init__定义构造函数来对类进行实例化,如:

            这种情况下,实例化的时候就需要加入参数了

                    test2 = testClass2('bill', 25)

                    test2.get_Name()

                    test2.age

    3.3 实例对象

            唯一被实例对象接受的操作是属性引用,包括数据引用和方法引用,用法如上:

            test2.age是数据属性的引用

            test2.get_Name() 是方法属性的引用

    3.4 方法对象

            在上例中,test2.get_Name 就是一个方法属性的引用,返回的是一个方法对象,如果要调用这个方法,就可以用 test.get_Name() (注意,加了括号就是调用,不加就是方法对象)

            既然test2.get_Name是一个方法对象,那它就可以赋值给一个变量,用这个变量来调用该方法,如: 

            t = test2.get_name         # 赋值过程,赋值方法对象

            t()                                    #调用该方法

    3.5 类变量和实例变量

            简单来说,实例变量就是每个类的实例特有的变量,类变量就是类的各个实例所共享的变量,下面的这个例子很好的说明这个问题 :

        在上例中,通过构造函数__init__()来定义的变量就是实例变量,因为实例是通过类的构造函数来进行实例化的,而kind是定义类的时候定义的变量,是这个类的固有变量,叫类变量,类的每个实例都会共享这个类变量

4. 继承

    一个类继承另一个类,只是在类名后面多了一个要继承的类的字名,其余定义方法一样,格式如下:

    新定义的类叫衍生类(子类),被继承的这个类叫基类(父类)

    继承之后,子类可以直接调用父类中已经定义的方法,如果父类中方法不能满足要求时,在子类中可以重写这个方法,调用时,子类的方法要比父类的同名方法优先级要高,会优先被调用。

    子类中直接调用父类的方法:父类名.方法名(self, 参数)

    4.1 多态继承

           一个子类同时继承多个父类,格式如下:

        在多态继承中,子类调用父类方法的时候,先查找第一个父类(及其父类的父类的父类。。。)中方法,找不到的话再找第二个父类,以此类推

5. 私有实例变量

    私有实例变量是不能从类的外部直接接接触的变量,只能通过调用类的方法来获取或操作私有变量,这样的好处是保护数据的私密性,但在python中,真正意义上的私有变量是不存在的

    传统上,从代码格式的形式上来定义私有变量,在python中,以下划线开头的变量名被认为是私有变量,不应该从外部直接获取或修改(其实是可以的,只是这样定义)

6. 空类

    类似于c语言中的struct数据类型,可以定义一个空类把命名的数据绑定在一起存储起来,如下:

7. 迭代器

    使用 for 可以遍历迭代器中的每一个value, 原理如下:

    (1) for 调用 iter()方法作用在一个容器对象上,返回一下迭代器对象

    (2) 迭代器对象定义了__next__()方法,可以一次一个获取容器中元素

    (3) 当没有元素的时候,__next__() raise StoIteration 异常

    (4) for 接受到该异常信息而停止循环

    例子如下:

    通过定义__iter__ 和 __next__方法来自定义一个迭代器:

8. 生成器

    生成器是生成迭代器的一个有效的方式,可以定义函数的形式来创建生成器,只不过把return 改为关键字 yield, 如下:

    可以用生成器创建迭代器的,也都可以用基于类的方法通过实现__iter__和__next__方法来创建迭代器,但是生成器的方法会更简单一些,因为它已经自动创建了__iter__和__next__方法

9. 生成器表达式

    一些简单的生成器可以用类似列表推导式的方法来创建,但是要把列表推导式的中括号换成小括号    

    试用情况:生成器马上应用于一个闭合函数中

    特点:简洁,内存友好,不灵活

    如下例:

本篇内容较多,且不容易理解,新手可以先把数据结构以及常用的内置函数,概念掌握清楚再学习这一部分会好一些,详细请参考官方文档:https://docs.python.org/3/tutorial/classes.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容