【Python开发】7. 类与面向对象

本文专栏:Python开发笔记  点击查看系列文章

1. 面向对象编程

面向对象编程 是最有效的软件编写方法之一。

在面向对象编程中,现实世界中的事物和情景,均可以使用 来编写表示。将要描述的对象提取公共行为,编写成类。

基于编写的类,可以创建 对象 ,使得每个对象自动具备所提取的公共行为。

然后可根据实际情况,赋予每个对象自己独有的特性。

上面描述的根据类来创建对象的过程,被称为 实例化 。这让你能够使用 类的实例

2. 类的创建和使用

2.1 创建类

使用 几乎可以模拟任何东西。

比如 学生类Student ,可以用来表示任意学生。任意学生包含的信息都有 学号no姓名name籍贯nativePlace 等。对于每个学生的行为,都有 上课attend Class下课finish Class 等。

所以可以创建 Student类 来表示。

示例(student.py):

class Student():

    def __init__(self, no, name, nativePlace):
        """初始化属性no, name, nativePlace"""
        self.no = no
        self.name = name
        self.nativePlace = nativePlace

    def attend_class(self):
        print(self.name + '正在上课')

    def finish_class(self):
        print(self.name + '已经下课')

关于这个类的定义,几点说明及注意事项如下:

  • Student:这是类的名字。约定所有单词的首字母大写。
  • 类中的函数称为方法
  • _init_() :初始化方法,当根据Student类来创建实例时,该方法将自动执行。约定开头和末尾各有两个下划线,避免命名冲突。
  • _init_()中的self:self形参必不可少,还必须位于其他形参之前。这是因为类的创建、调用时,都自动传递实参self,这个self是一个指向实例本身的引用,使得实例能够访问类中的属性和方法。当创建实例时,self不需要传递参数,只需要给后边的值(no、name等)赋值即可。
  • 属性:像上面的no、name变量,在初始化时,均使用了self 前缀,这种变量可以给类中的所有方法使用,还可以通过类的任何实例来访问,这种变量称为属性。
  • 其他方法:如attend_class()和finish_class()方法,一般为当前类的具有的通用方法,其中的参数self使得该方法能够访问类中的属性。这些方法可以继续添加其他的,不在属性内的形参。
  • 私有方法和属性:Python约定名称以双下划线“__”开头但不以它结尾的方法或属性,都是私有的,其他则都不是私有部分。
2.2 使用类和示例

类如何来使?先看下面这个示例。

示例:

class Student:

    def __init__(self, no, name, nativePlace):
        """初始化属性no, name, nativePlace"""
        self.no = no
        self.name = name
        self.nativePlace = nativePlace
        # 【 1 】这里也可以给属性指定默认值
        self.school = '武汉理工大学'

    def attend_class(self):
        return self.name + '正在上课'

    # 【 2 】类中的方法,可以增加必要的形参
    def attend_class_2(self, address):
        return self.name + '正在 ' + address + ' 上课'

    def attend_class_3(self, address):
        return self.name + '正在 ' + self.school + address + ' 上课'

    def finish_class(self):
        return self.name + '已经下课'


# 使用类
# 【 3 】根据类创建实例
zhangSan = Student(20200101, '张三', '湖北武汉')
# 【 4 】访问属性
print('创建了一个示例,学生姓名是: ' + zhangSan.name)
# 【 5 】调用方法
print(zhangSan.attend_class())
print(zhangSan.attend_class_2('第一教学楼101教室'))
print(zhangSan.attend_class_3('第一教学楼101教室'))

示例输出:

创建了一个示例,学生姓名是: 张三
张三正在上课
张三正在 第一教学楼101教室 上课
张三正在 武汉理工大学第一教学楼101教室 上课

注:最新的Python中,class关键字后面的类名后边的括号()可以省略

在这个类的使用的示例中,主要有这么几点:

  • 【1】 类中的属性可以给指定默认值。
  • 【2】类中的方法,可以增加必要的形参。
  • 【3】根据类来创建实例的方法如上,即 实例名 = 类名(实参1,实参2……) 。可以创建多个实例。
  • 【4】可以直接通过 实例名.属性名 的格式来访问示例的属性。
  • 【5】可以直接通过 实例名.方法 的格式来调用示例中的方法,其中有额外参数的需要在调用时给出。

可以对属性的值进行修改,主要有三种方法:

  1. 直接通过示例进行修改
  2. 通过方法进行设置
  3. 通过方法进行递增(即类中的某个方法实现的是递增或自加,可以多次调用这个方法实现对属性的修改。

示例:

# 创建类
class Student:

    def __init__(self, no, name, nativePlace):
        """初始化属性no, name, nativePlace"""
        self.no = no
        self.name = name
        self.nativePlace = nativePlace
        # 【1】这里也可以给属性指定默认值
        self.school = '武汉理工大学'

    def attend_class(self):
        return self.name + '正在上课'

    # 【2】类中的方法,可以增加必要的形参
    def attend_class_2(self, address):
        return self.name + '正在 ' + address + ' 上课'

    def attend_class_3(self, address):
        return self.name + '正在 ' + self.school + address + ' 上课'

    def finish_class(self):
        return self.name + '已经下课'

    def setSchool(self, school):
        self.school = school
        # 这里不仅可以简单的赋值,还可以实现更多功能


# 使用类
liSi = Student(20200102, '李四', '江苏南京')
# 直接通过属性名修改
liSi.school = '南京理工大学'
print(liSi.attend_class_3('第二教学楼102'))
# 通过方法修改属性
liSi.setSchool('华中科技大学')
print(liSi.attend_class_3('第二教学楼103'))

示例输出:

李四正在 南京理工大学第二教学楼102 上课
李四正在 华中科技大学第二教学楼103 上课

3. 继承

编写类时,并非总是要从空白开始。如果要编写的类是另一个现成类的特殊版本,可使用继承。

一个类 继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为 父类 (也叫做 超类(superClass) ) ,而新类称为 子类子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法

比如,学生都需要上课和下课。在学生这个群体中,有参加学生工作的(如monitor),还有参加志愿服务的(如volunteer)。所以这两类学生,具体普通学生的属性,还有自己的特有属性。那么这两类学生的定义可以采用继承来实现。

可以通过下面这个示例来理解继承的具体使用。

示例:

# 父类
class Student:
    # 初始化
    def __init__(self, no, name, nativePlace):
        self.no = no
        self.name = name
        self.nativePlace = nativePlace
        self.school = '武汉理工大学'

    def attend_class(self):
        return self.name + '正在上课'

    def finish_class(self):
        return self.name + '已经下课'


# 【 1 】monitor子类
class Monitor(Student):
    # 【 2 】子类初始化
    def __init__(self, no, name, nativePlace):
        # 【 3 】初始化父类的属性
        super().__init__(no, name, nativePlace)
        # 【 4 】定义子类属性
        self.classRoom = '第五教学楼-107教室'
        self.meetingRoom = '321会议室'

    # 【 5 】定义子类方法
    def attend_A_Meeting(self):
        return self.name + ' 正在' + self.meetingRoom + ' 开会'

    # 【 6 】重写父类方法
    def attend_class(self):
        return self.name + ' 正在' + self.school + self.classRoom + ' 上课'


# 使用类
liSi = Monitor(20200103, '李四', '湖北武汉')
print(liSi.attend_A_Meeting())
print(liSi.attend_class())

示例输出:

李四 正在321会议室 开会
李四 正在武汉理工大学第五教学楼-107教室 上课

在这个示例中,对子类的定义主要有这么几点:

  • 【1】创建子类是,class关键字后面的子类名后的括号内填写继承的父类名。
  • 【2】子类初始化方法的形参,除了包含父类初始化方法的形参外,还可以增加子类独有的形参
  • 【3】初始化父类属性的方法如上示例,使用了super()方法,即 super().__init__(父类形参1,父类形参2,……)
  • 【4】子类独有的属性需要单独定义
  • 【5】定义子类自己的方法,根据前述要求定义即可。
  • 【6】子类可以对父类的方法进行重写。

另外,可以将一个类的示例,用作另一个类的属性。

4. 导入类

4.1 模块中存储类

在一个模块中,可以存储一个或者多个类。即一个模块可以根据需要,存储任意数量的类

示例(student.py):

# 父类
class Student:
    # 初始化
    def __init__(self, no, name, nativePlace):
        self.no = no
        self.name = name
        self.nativePlace = nativePlace
        self.school = '武汉理工大学'

    def attend_class(self):
        return self.name + '正在上课'

    def finish_class(self):
        return self.name + '已经下课'


# monitor子类
class Monitor(Student):
    # 子类初始化
    def __init__(self, no, name, nativePlace):
        # 初始化父类的属性
        super().__init__(no, name, nativePlace)
        # 定义子类属性
        self.classRoom = '第五教学楼-107教室'
        self.meetingRoom = '321会议室'

    # 定义子类方法
    def attend_A_Meeting(self):
        return self.name + ' 正在 ' + self.meetingRoom + ' 开会'

    # 重写父类方法
    def attend_class(self):
        return self.name + '正在' + self.school + self.classRoom + '上课'


# volunteer子类
class Volunteer(Student):
    # 子类初始化
    def __init__(self, no, name, nativePlace, community):
        # 初始化父类的属性
        super().__init__(no, name, nativePlace)
        # 定义子类属性
        self.serviceCommunity = community

    # 定义子类方法
    def attend_A_Voluntary(self):
        return self.name + ' 正在 ' + self.serviceCommunity + ' 志愿服务'

在上面这个模块中,定义了三个类。

4.2 从模块导入类

可以从模块中导入一个类,也可以导入多个类,也可以导入整个模块,也可以导入模块中的所有的类,也可以在一个模块中导入另一个模块。

下面这个示例,展示了如何导入。

示例:

# 导入单个类,并命名别名
from student import Student as Sd

# 导入多个类
from student import Monitor, Volunteer

# 导入全部类
from student import *

# 导入整个模块
import student

示例:

# 导入整个模块
import student

# 使用类
liSi = student.Volunteer(20200104, '李四', '湖北武汉', '余家头社区')
print(liSi.attend_A_Voluntary())

示例输出:

李四 正在 余家头社区 志愿服务

关于模块的导入,有几点建议。

  • 一般用到模块中的哪个或者哪几个类,就导入哪个类或者哪几个类。主要是清楚的知道程序使用了哪些类。
  • 如果用到了一个模块中的很多类,最好导入整个模块,然后使用 模块名.类名 的形式来访问类。

5. 类的编码风格

  • 类名应采用驼峰命名法 ,即将类名中的每个单词的首字母都大写,而不使用下划线。
  • 实例名和模块名都采用小写格式,并在单词之间加上下划线。
  • 对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。
  • 每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
  • 可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
  • 需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import 语句,再添加一个空行,然后编写导入你自己编写的模块的import 语句。包含多条import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。

参考文献:

[1] Python编程:从入门到实践

如果有帮助,感谢动动小手点个赞 (๑•̀ㅂ•́)و✧❤

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾年之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值