7.2 类和对象
7.2.1 创建第一个类
Python使用class关键字表示类,下面是一个最简单的类:
class Car: pass
关键字class代表当前代码是一个类的定义,Car表示当前类的名字,其后有一个冒号,冒号后的代码是类的具体实现,本例中的类体为空。
空类在现实中没有什么意义,所以我们根据需求对这个类进行扩展。
汽车包含品牌和颜色属性,同时还可以行驶,所以根据以上分析给Car类添加属性和方法:
现在一个汽车类已经创建好了,它的默认品牌是“宝马”,颜色是“红色”,还有一个行驶的方法。
7.2.2 实例化
定义好类之后,就需要使用该类了,首先创建一个类的实例,这就好比需要一辆真正的汽车才可以上路一样,Python不像其他语言需要new关键字来实例化类,Python只需要使用类名+()就可以实例化一个类:
>>> a = Car()
使用点(.)来调用属性与方法:
>>> print("品牌:", a.brand, ", 颜色:", a.color) 品牌: 奔驰, 颜色: 红色 >>> a.run(50) 当前行驶速度: 50 km/h
注意,读者可能会对a.brand这样的用法感觉有点奇怪,其实这样确实不合适,后面会具体介绍。
7.2.3 self参数
在这里,读者可能注意到run函数有两个参数,其中第一个参数是self,而在调用的时候并没有传递值给self,这其实是Python规定的类的方法必须要有的一个参数,并没有什么特殊意义,在调用的时候也不需要给它传值。可以为Car类添加一个print_self方法查看self到底是什么。
调用print_self方法:
>>> a = Car() >>> a.print_self()
输出:
<__main__.Car object at 0x0000000003103EF0> <class '__main__.Car'>
从以上输出结果可以看出,self代表当前类的实例,而self.__class__就是Car类。
7.2.4 类变量
像brand、color这类变量叫作类变量,是所有类实例共享的变量。类变量定义在类中但是不属于任何函数。虽然可以像前面例子一样使用类实例来访问并修改类变量,但是不建议这样做,因为当某一个类实例修改了类变量后,可能会对其他类实例的使用造成影响,也会使开发人员难以确定当前类变量的值,尤其是可变对象的值。
正确的用法是使用“类名.属性”的方式访问类的属性:
>>> print(Car.brand) 宝马
创建两个Car实例,查看它们的brand:
>>> a = Car() >>> b = Car() >>> print(a.brand, id(a.brand)) 宝马 40826552 >>> print(b.brand, id(b.brand)) 宝马 40826552
可见两个实例的brand属性所指向的内存地址相同,这就意味着如果修改了Car.brand,那么实例a和b的brand值都会发生变化:
>>> Car.brand = "奔驰" >>> a = Car() >>> b = Car() >>> print(a.brand, id(a.brand)) 奔驰 51218544 >>> print(b.brand, id(b.brand)) 奔驰 51218544
7.2.5 实例变量
看到类变量的特性,可能会想到对于品牌与颜色这类属性,每辆汽车都可能不相同,那么在Python里面要如何表示呢?
对于这种类型的属性,可以使用实例变量来存储,实例变量是定义在方法中的变量,只能用于当前类的实例。使用实例变量修改上面代码:
方法__init__()叫作构造函数,每当实例化一个类时都会执行这个函数,通常会在这个函数里面为实例属性进行初始化,所以也叫作初始化方法。此时再实例化Car类时就必须按照__init__()的格式实例化了,不能直接使用Car()的方式了:
>>> a = Car("宝马", "红色") >>> a.print_car() 品牌: 宝马 , 颜色: 红色 >>> b = Car("奔驰", "黑色") >>> b.print_car() 品牌: 奔驰 , 颜色: 黑色