Python 类与对象
面向对象的编程思想力图在程序中对事物的描述与现实中的形态保持一致。
其中有两个重要概念是类与对象:
- 类:对某一类事物的抽象描述,用于描述多个对象的共同特征,它是对象的模板
- 对象:用于表示现实中该类事物的个体,用于描述现实中的个体,它是类的实例
面向对象的设计特点是模块化,即实现一个功能(整体),把它拆分为多个模块去实现,最后把模块结合起来,使复杂的过程简单化。
类
编写类时,定义一些对象都有的通用行为和属性。基于类创建对象时,每个对象都自动具备这种通用属性和行为:
- 方法:类中的函数
- 属性:通过实例访问的变量
创建类
使用关键字 class 创建类,类似于创建函数,使用复合语句。类名使用驼峰 CamelCase 命名风格,每个单词首字母大写
class Dog:
# 定义类级别的变量/属性
scientific_name = "Canis lupus familiaris"
# 定义实例级别变量,该方法在创建实例时自动运行,且需要传递一个实参
def __init__(self, name):
self.name = name
# 定义方法
def speak(self):
print("Woof!")
- 在定义类方法时第一个形参十分特殊,一般命名为
self(也可以命名为其他)指代对象本身。创建实例时,类的方法的第一个形参self的实参自动传入(用户不需要提供值),它是一个指向实例本身的引用,让实例能够访问类中的属性和其他方法。(self扮演者在类中各个方法沟通唤醒的信使) - 类似地以
self为前缀的变量可以供类中所有方法使用(全局变量)
类级别属性
在类定义中设置的变量(预设变量值),可以适用于所有实例,即所有依据该类创建的对象,该变量的变量值都相同。
特殊方法 init
方法 __init__() 是一个特殊的方法(双下划线,Dunder 方法),其中 init 表示初始化,即该方法在创建实例时会自动运行(而类中的其他方法需要在实例建立后,用户主动调用时才运行)
- 方法
__init()__一般在该方法中初始化新对象的一些参数值 - 方法
__init__()创建实例时并未显式地包含 return 语句,但是 python 会自动返回一个实例,因此需要将实例存储在变量中 - 方法
__init__()定义中的形参self必不可少,且必须位于第一位
对象
根据类来创建对象被称为实例化。创建实例后,每个实例都是独立个体,即使实例输入的实参相同。因此每个实例都需要存储在不同的变量中。
创建对象
创建新对象是通过调用类,类似于调用函数或方法,返回该类的新对象。根据类创建的实例名称用小写。
Warning
对于自定义的类,需要在创建此类对象前,将定义该类的脚本导入(不需要后缀 .py)
import class_file_name
查询所属类
在 Python 中判断是否为对象的方式之一是询问是否能作为变量的值,如字符串、打开的文件,甚至函数都是对象。
查看对象是属于哪一个类,可以使用函数 isinstance() 或 type()
- 函数
isinstance()询问特定的对象是否属于特定的类,返回True或False - 函数
type()返回特定类型
>>> isinstance(42, int)
True
# True 也是布尔值(类 bool)。实际上,所有布尔值也是 int。
>>> isinstance(true, int)
True
>>> type(42)
<class 'turtle.Turtle'>
提示
Python 常见的内置类型
- 整数
int - 浮点数
float - 布尔值
bool(True和False) - 字符串
str(针对文本)
可以使用以下内置函数将对象更改到相应的内置类型
- 改变为整型
int() - 改变为浮点型
float() - 改变为字符型
str()
访问属性
使用句点法,指定实例的名称和属性名称,并用句点 . 分隔它们,返回属性的值
调用方法
使用句点法,指定实例/对象的名称和方法名称,并用句点 . 分隔它们;若该方法有形参,需要传递实参
继承
在程序中,继承是事物之间的所属关系,即子类继承父类(或超类)。
继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有的属性和方法,同时可以增添属于自己专有的属性和方法,或修改父类的属性和方法。
继承的好处:
- 提高了代码的复用性
- 让类与类之间产生了关系,为多态提供了前提
Python 继承类的方法是在新类定义的括号里(第一行)填入需要继承的类
# Husky 类继承于 Dog 类
class Husky(Dog):
# 添加新属性,来源地
origin = "Siberia"
# 修改父类方法
def speak(self):
print("Awooo!")
super 函数
当子类使用了 __init__ 方法进行了专属的初始化设置时,一般需要在该方法中先调用方法 super().__init__()
import turtle
# 创建一个 turtle 子类
class BigOrangeTurtle(turtle.Turtle):
def __init__(self):
# 先调用父类初始化(预初始化)
super().__init__()
# 对于子类的专属初始化,修改默认颜色为橙色,线宽为 10
self.color("orange")
self.width(10)
super() 函数返回一个父类对象,super().__init__() 即使用父类的 __init__() 方法先进行初始化, 接着再执行剩下的语句,即针对该子类的专属初始化设置,以免因为在子类直接覆盖了父类的 __init__ 方法引起异常。
pass 语句
在定义类时希望创建一种方法但什么也不执行,pass 即是什么也不执行语句,可以用在类或方法定义里(因为在 Python 里不能有不包含任何语句的函数或类),可实现占位符的作用以在子类里被替换。
查询所属父类
使用函数 issubclass(subclass_name, parent_class_name) 查询前一类是否为后一类的子类,返回 True 或 False 值
# bool 类是 int 的子类
>>> issubclass(bool, int)
True
Warning
类的常见关系有两种
Is-a从属关系,即继承关系,如Husky是DogHas-a包含关系,即在该类中使用(包含)了另一类(但并非继承,使用了该类的实例),如Dogpark中含有Dog。这种情况需要使用import语句导入定义另一类的脚本
⚙ 示例文件