前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python入门(16)

Python入门(16)

作者头像
高一峰
发布2020-09-22 09:54:16
8470
发布2020-09-22 09:54:16
举报
文章被收录于专栏:高渡号外
Python入门(16/18)

第十六节 面向对象编程

大家好,目前为止,我们编写的python代码,有一个基本的特征,就是根据需求,围绕函数,设计程序,处理数据。即使面临相对复杂的问题,通过函数、模块和包等解决方案,也能帮助我们解决程序架构和代码复用问题。但是,这样的编程方式还是被称作面向过程的编程。

说简单点,本质上,还是一种线性化的编程方式。虽然python的独特性,足以支撑其面向过程的编程依然会大行其道,并且,在处理很多问题时游刃有余。但是,相比其他高级语言的面向对象的编程方式来说,面向过程的编程方式必然存在一定的局限性。

那么,今天,我们就来讲讲什么是Python面向对象的编程。

1、面向对象编程的基石:类与实例

类与实例是面向对象编程的基石。一个类(Class)能够创建一种新的类型(Type),其中对象(Object)就是类的实例(Instance)。

这个比较抽象的概念,我们可以这样来理解,比如:

  • 系统有一个内置的整数类型,就是int类型。
  • 然后,你定义了一个 int 类型的变量 x。
  • 那么,意味着你根据int类,创建了一个 int 类的实例 x(对象)。

2、类的字段、方法、属性

类可以包括字段(Field)和方法(Method)。

在python里,我们可以简单地这样理解这些概念:

字段,就是隶属于类的变量。

方法,就是隶属于类的函数。

关于字段,它有两种类型:

(1)隶属于类的实例(对象)的字段,被称作实例变量(Instance Variables);

(2)从属于某一类本身的字段,被称作类变量(Class Variables)。

关于方法,它有一个特殊的参数self

与普通函数的区别:除了它隶属于某个类,在它的参数列表的开头,还需要添加一个特殊的参数 self ,但是你不用在调用该方法时为这个参数赋值,Python 会为它提供。

事实上,当你调用一个类的方法时,Python 将会自动将self参数转换成 myobject,所以,你无需为其赋值。这同时意味着,如果你的类里面的方法没计划有参数,你依旧必须为它添加 一个self 参数 。

PS:Python中的 self 相当于 C++ 中的 this 指针,Java 与 C# 中的 this 引用。

3、类的创建

通过 class 关键字可以创建一个类。

类的名称后跟一对括号,就创建一个类的实例。

接下来是一个缩进的语句块,代表这个类的主体。

示例16_1:本例中,我们使用 pass 语句创建了一个空代码块。

运行结果显示: myclass 类的 __main__ 模块中拥有了一个实例MyClassObject,并显示了它在内存中存储该对象的地址。当然,你看到的地址应该不会相同,因为 Python 会在它找到的任何空间来存储对象。

4、方法的创建

类定义一个方法(Method)其实很简单,就像定义一个函数一样,唯一的不同在于它的方法还拥有一个额外的 self 参数。

示例16_2

这里我们就能看见 self 的存在了,请注意, 调用say_hi() 这一方法原本并不需要参数,但是我们还是要在方法的定义中提供 self 参数。

5、__init__ 方法

这种前后都带有双下划线的方法,是属于python内置的专用方法。

这里我们来了解一下 __init__ 方法究竟有什么特殊意义?

__init__ 方法会在它的类被实例化(Instantiated)时立即运行。这一方法可以对任何你想进行操作的目标对象进行初始化(Initialization)操作。

这里你要注意在 init 前后加上的双下划线。

代码解析:

(1)、在本例中,我们定义2个name变量,但它们并不相同,更不会造成混淆。因为 self.name 中的点号意味着它的“name”是“self”对象的一部分,而另一个 name 则是一个纯粹的局部变量。

(2)、MyClass 类的实例调用了say_hi()方法,但是,并没有显式地调用__init__() 方法,然而它已经运行了。这正是这个方法的特殊之处。

6、类变量与实例变量

字段和方法都是类的属性。

我们已经知道,方法实现类的功能。那么字段呢?字段则用于存储类的数据。

作为数据的存在形式,字段其实就是绑定(Bound)到类与对象(即类的实例)的命名空间(Namespace)中的普通变量。意思是,我们定义的类的字段,仅在这些类与对象所存在的地方(被称作“上下文中”)有效。再简化一点:字段其实就是绑定到类的命名空间中的普通变量,并且,仅在这些类所存在的地方有效。

字段(Field)的两种类型 —— 类变量实例变量

类变量(Class Variable)是共享的(Shared)——它们可以被属于该类的所有实例访问(使用)。该类变量只拥有一个副本,当任何一个对象对类变量作出改变时,发生的变动将在其它所有实例中都会得到体现。

实例变量(Object variable)由类的每一个独立的实例(对象)所拥有。在这种情况下,每个对象都拥有属于它自己的独立字段,也就是说,它们不会被共享,也不会以任何方式与其它不同实例中的相同名称的字段产生关联。

代码解析:

(1)、定义了一个类变量x,它将在类的所有实例中有效,注意:使用时需要前置类名,如MyClass.x。

(2)、在方法一中我们还故意定义了一个同名的局部变量:x=-1。请注意,它并不能因此影响到方法二中的x的值。

7、类的继承

面向对象编程的一个显著特征(也是一大优点)就是对代码的重用(Reuse),而重用的实现方法之一就是继承(Inheritance)。

下面讲一个关于继承的示例,设计需求是:假设一个应用涉及大学的老师和学生。其中一些特征是他们共有的,如:姓名、年龄、地址。而另外一些特征,如:教师的薪水、课程、假期,学生的成绩和学费,则是各自独立拥有的。

解决方案中,可以分别为他们创造两个“独立且笨重”的类,来处理信息。

但有一种更好的方法,是创建一个公共类叫作 SchoolMember ,然后建立两个子类:教师(Teacher )子类 和学生(Student)的子类,并让它继承SchoolMember类。然后,再向这些子类型中添加一些必要的独有的特征。

父类 SchoolMember ,又被称作基类(Base Class)或是超类(Superclass)。

子类:Teacher 和 Student类会被称作派生类(Derived Classes)或是子类(Subclass)。

(1)、先建一个学校类:SchoolMember,即:父类(基类)

(2)、再建两个子类:Teacher 和 Student。

请注意:它们通过类名后面的圆括号声明父类。

(3)、调用子类

#代码执行,输出:

(Initialized SchoolMember: 张老师)

(Initialized Teacher: 张老师)

(Initialized SchoolMember: 小明)

(Initialized Student: 小明)

Name:"张老师" Age:"40" Salary: "30000"

Name:"小明" Age:"25" Marks: "75"

8、类与类的继承的几个重要特性

(1)、类从基类中继承属性(字段和方法)

实际操作中,我们可以可以通过在子类中的方法名前面加上基类名做前缀,再传入 self 和其余变量,来调用基类的方法。

比如,在 Teacher 和 Student 子类中,我们可以直接用基类中的方法:SchoolMember.tell(self)

(2)、实例会继承所有可读取类(子类和父类)的属性(字段和方法)

案例中,当我们使用 SchoolMember 类的 tell 方法时,你会发现被调用的是子类型的 tell 方法,而不是 SchoolMember 的 tell 方法。这是因为 Python 总会从当前的实例的类型中开始寻找方法。如果找不到,它就会在该类所属的基类中继续查找。

(3)、如果子类中定义了__init__ 方法,将优先被调用,如果此时需要调用基类的__init__ 方法,则需要显式地进行调用。除非子类中未定义__init__ 方法,那么,类的__init__ 方法将自动执行。

比如,我们在 Teacher 和 Student 子类中定义了 __init__ 方法, Python 就不会自动调用基类 SchoolMember 的构造函数,必须自己显式地调用它。相反,如果我们没有在子类中定义 __init__ 方法,Python 将会自动调用基类的该方法。

(4)、修改父类的任何功能,它将自动反映在子类中。相反,子类的修改,则不会影响到其他的子类。

比如,案例中,你可以通过简单地向 SchoolMember 类进行操作,来为所有老师与学生添加一条新的 ID 卡字段。

小结

Python 是高度面向对象的,从长远来看,你不可能永远只做小应用,了解这些概念将对你大有帮助。

预告

下节课,我们将学习如何处理输入与输出,以及如何在 Python 中访问文件,这也是Python中极其重要和应用广泛的一个知识点。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 高渡号外 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档