Django 2.0 入门与实践
上QQ阅读APP看书,第一时间看更新

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()
    品牌: 奔驰 , 颜色: 黑色