Python Class
简介
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。
面向对象技术简介
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例图,Dog是一个Animal)。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
何时使用类
- 数据与操作紧密相关
- 对象有许多状态需要维护,可以使用类中的属性来保存状态。
- 需要生成多个仅在部分属性不同的实例,可以使用类作为模板。
- 不同对象存在公共parent-child的层次关系,可以使用继承来复用代码。
- 隐藏对象的实现细节,只对外公开接口。
类变量 与 实例变量
在Python中,类变量和实例变量是两个不同的概念:
- 类变量(Class Variable)
- 定义在类内部,但不在任何方法之内
- 被该类的所有实例对象所共享
- 可以通过类名或实例对象访问
- 用于定义与这个类相关的特征或属性
- 实例变量(Instance Variable)
- 定义在类内部的方法之内
- 每个实例对象拥有属于自己的变量副本
- 只能通过实例对象访问
- 用于定义实例对象的个性化特征或状态
例如:
1 | class Person: |
综上,类变量用于定义类的通用属性,实例变量用于定义实例的独特属性。区分二者是理解Python面向对象的关键。
创建
1 | class Employee: |
类函数必有参数 ‘self’
必须有一个额外的第一个参数名称, 按照惯例它的名称是 self,self 不是 python 关键字,换成其他词语也行。
创建实例对象与访问
1 | emp1 = Employee("Zara", 2000) |
继承
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
继承语法 class 派生类名(基类名)
调用基类
调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
,这点在代码上的区别如下:
1 | class Base: |
在Derived类中:
调用Base基类的方法base_method(),需要写成Base.base_method(self)
调用普通函数print(),直接写函数名即可
区别在于:
- 调用基类方法需要指明方法所属的基类
- 基类方法需要传入self,指代实例自己
而对于普通函数,只需要直接调用即可,不需要self参数。
这与Python的名称空间和面向对象实现有关,是理解Python类继承的关键点。
运算符重载
1 | __init__ : 构造函数,在生成对象时调用 |
+=
在Python中可以通过特殊方法__iadd__来对+=符号进行重载。
__iadd__需要定义在类中,用于指定+=操作时的具体行为。例如:
1 | class Vector: |
这里我们定义了__iadd__方法,用于实现两个Vector对象使用+=时的相加操作。
__iadd__方法的参数是另一个要相加的对象,在方法内部我们实现了两个向量的分量相加,并返回self作为结果。这样就实现了+=的运算符重载。
此外,Python还提供了__add__特殊方法用于重载+符号,但是__iadd__和__add__有以下区别:
- __add__返回一个新的对象,不改变原有对象。
- __iadd__在原有对象的基础上进行操作,并返回对原对象的引用。
所以对可变对象进行+=操作时,通常需要实现__iadd__方法。