第八章 类

8.1 创建和使用类

8.1.1 创建类

class Dog():
    """模拟小狗的类"""
    def __init__(self, name, age):
        """ 初始化类信息"""
        self.name = name
        self.age = age
    
    def sit(self):
        print(self.name.title() + " sit down!")
    
    def roll(self):
        print(self.name.title() + " roll over!")
  1. 方法__init__()
- 类中的函数称为方法 ;你前面学到的有关函数的一切都适用于方法。
  • 方法__init__()是一个特殊的方法,每当你根据Dog类创建新实例时,Python都会自动运行它。
  • 在这个方法的名称里,开头和末尾都有两个下划线,这是一种约定,为了避免与普通方法名称冲突
- 该方法里有三个形参:self、 name和age。其中self是必不可少的,还必须放在所有参数前面。因为每个与类相关联的方法都调用都自动传递self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。我们创建Dog实例时,Python将调用__init__()方法。我们通过实参向Dog()传递名字和年龄,而self会自动传递。所以每次我们只需要给最后两个形参(age和name)即可。
  • 在方法__init__()的定义中,两个变量都有前缀self。以self为前缀的变量都可供类中的所有方法使用,可以通过类的任何实例访问这些量。
    self.name=name获取存储在形参name中的值,并存储到变量name中,然后该变量被关联到创建的实例。
像这样可以通过实例访问的变量称为属性
  1. Dog类还定义了另外两个方法:sit()和roll()。由于这些方法不需要额外的信息,因此他们只有一个形参self。

8.1.2 根据类创建实例

可将类视为有关如何创建实例的说明。

class Dog():
   ...

my_dog = Dog('Tim', 2)
print("My dog's name is " + my_dog.name)
print("My dog's age is " + str(my_dog.age))
my_dog.sit()
my_dog.roll()

My dog's name is Tim

My dog's age is 2
Tim sit down!
Tim roll over!

8.2 继承

一个类继承另一个类时,它将自动获得另一个类的所有属性和方法

8.2.1 子类的方法 __init__()

创建子类的实例时,Pyhton首先需要完成的是给父类的所有属性赋值。为此,子类的init方法需要父类“施以援手”。

例如,下面来模拟电动汽车,其为继承自“车”的子类。

class Car():

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def get_name(self):
        long_name = self.make + ' ' + self.model + ' ' + str(self.year)
        return long_name.title()


class ElectricCar(Car):

    def __init__(self, make, model, year):
        super().__init__(make, model, year)


my_tesla = ElectricCar('tesla', 'model', 2016)
print(my_tesla.get_name())

Tesla Model 2016

  • 定义子类时,必须在括号内指定父类的名称
  • super()是一个特殊的函数,帮助Python将父类和子类关联。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的所有属性。父类又称超类(super class),super函数也是因此得名。

8.2.2 给子类定义属性和方法

让一个类继承另一个类之后,可以拥有自己独特的属性。
比如电动汽车有一项指标是电池容量

class Car():

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    ...


class ElectricCar(Car):

    def __init__(self, make, model, year, batterysize):
        super().__init__(make, model, year)
        self.batterysize = batterysize
    def get_bat_size(self):
        return self.batterysize

my_tesla = ElectricCar('tesla', 'model', 2016, 70)
print(my_tesla.get_bat_size())

70

8.2.3 重写父类的方法

对于父类的方法,只要不符合子类的"规则",都可以进行重写。即在子类中定义一个重名的方法,这样Python将不会考虑父类中的这个方法。
比如描述电动汽车的名字还需要带上电池容量,则需要重写get_name函数

class Car():

    ...

    def get_name(self):
        long_name = self.make + ' ' + self.model + ' ' + str(self.year)
        return long_name.title()


class ElectricCar(Car):

    ...
    def get_name(self):
        long_name = self.make + ' ' + self.model + ' ' + str(self.year) + ' ' + str(self.batterysize)
        return long_name.title()


my_tesla = ElectricCar('tesla', 'model', 2016, 70)
print(my_tesla.get_name())

Tesla Model 2016 70

8.2.3 将类作为其他类的属性

和C++类的嵌套相似,不多赘述

8.3 导入类

语法作用
from 模块名 import 类名导入单个类
from 模块名 import 类1,类2...导入多个类
import 模块名导入整个模块的类(使用需要加句点)
from 模块名 import *导入模块所有类 (使用不需要加句点)

8.3.1 在一个模块中导入另一个模块

模块可以连环导入,比如

## 8.4 Python标准库
Python标准库是Python内置的一组模块。只需在程序开头包含一条简单的import语句,便可使用标准库的函数和类。比如模块collections中的一个类——OrderedDict.
字典虽然能够把信息关联,但不能记录你添加键值对的顺序。而OrderedDict可以解决这个问题。

from collections import OrderedDict

fav_lang = OrderedDict()

fav_lang['Lily'] = 'C'
fav_lang['Tom'] = 'Python'
fav_lang['Jack'] = 'JAVA'

for name, lang in fav_lang.items():
    print(name + " " + lang)

Lily C
Tom Python
Jack JAVA

输出的顺序与添加的顺序完全相同。