9.1 创建和使用类
使用类几乎可以模拟任何东西。
9.1.1 创建一个类
1 | class Dog: |
- 类中的函数称为方法。
- 通过实例访问的变量称为属性。
方法__init__():方法__init__()是一个特殊方法,每当根据类创建一个新实例时,Python都会自动运行它。在这个方法的定义中,形参self必不可少,而且必须位于其他形参的前面。每个与实例相关联的方法调用都会自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
注意:方法__init__() 前后有两个_。
9.1.2 根据类创建实例
1 | class Dog: |
输出结果为:
1 | My dog`s name is willie |
- 访问属性
要访问实例的属性,可使用句点表示法。
1 | my_dog.name |
- 调用方法
要调用方法,可指定实例的名称和要调用的方法,并用句点分隔。
1 | my_dog.sit() |
9.2 使用类和实例
可使用类来模拟现实世界中的很多情景。类编写好后,大部分时间将花在根据类创建的实例上。可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。
9.2.1 修改属性的值
直接修改属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Dog:
"""创建一个类来模拟小狗"""
def __init__(self, name, age):
self.name = name
self.age = age
def sit(self):
"""模拟小狗收到命令时蹲下"""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""模拟小狗收到命令时打滚"""
print(f"{self.name} rolled over!")
my_dog = Dog('willie', 6)
print(f"My dog`s name is {my_dog.name}")
print(f"My dog is {my_dog.age} years old")
my_dog.age = 7 #直接修改属性的值
print(f"Now, My dog is {my_dog.age} years old")输出结果为:
1
2
3My dog`s name is willie
My dog is 6 years old
Now, My dog is 7 years old通过方法修改属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Dog:
"""创建一个类来模拟小狗"""
def __init__(self, name, age):
self.name = name
self.age = age
def sit(self):
"""模拟小狗收到命令时蹲下"""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""模拟小狗收到命令时打滚"""
print(f"{self.name} rolled over!")
def add_age(self, add_value):
self.age = self.age + add_value
my_dog = Dog('willie', 6)
print(f"My dog`s name is {my_dog.name}")
print(f"My dog is {my_dog.age} years old")
my_dog.add_age(2)
print(f"Now, My dog is {my_dog.age} years old")输出结果为:
1
2
3My dog`s name is willie
My dog is 6 years old
Now, My dog is 8 years old
9.3 继承
编写类时,并非总是要从空白开始。如果要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。
9.3.1 子类的方法__init__()
在既有类的基础上编写新类时,通常要调用父类的方法__init__()。这将初始化在父类__init__()方法中定义的所有属性。从而让子类包含这些属性。
1 | class Dog: |
输出结果为:
1 | My dog`s name is sea_willie |
super()是一个特殊函数,能够调用父类的方法。父类也称为超类(superclass),名称super由此而来。
9.3.2 给子类定义属性和方法
1 | class Dog: |
输出结果为:
1 | My dog`s name is sea_willie |
9.3.3 重写父类的方法
对于父类的方法,只要它不符合子类模拟的实物行为,都可以进行重写。
1 | class Dog: |
输出结果为:
1 | My dog`s name is sea_willie |
9.3.4 将实例用作属性
使用代码模拟实物时,可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分提取出来,作为一个单独的类。可以将大型类拆分成多个协同工作得小类。
9.4 导入类
随着不断给类添加功能,文件可能变得很长,即便妥善地使用了继承亦如此。为遵循Python的总体理念,应让文件尽可能整洁。Python在这方面提供了帮助,允许将类存储在模块中,然后在主程序中导入所需的模块。
9.4.1 导入单个类
1 | from module_name import ClassName |
9.4.2从一个模块中导入多个类
1 | from module_name import ClassName1, ClassName2, ClassName3 |
9.4.3 导入整个模块
1 | import module_name |
9.4.4 导入模块中的所有类
1 | from module_name import * |
9.4.5 使用别名
1 | from module_name import ClassName as CN |
9.5 Python标准库
Python标准库是一组模块,安装的Python都包含它。
模块random演示
在这个模块中,一个有趣的函数是randint()。它将两个整数作为参数,并随机返回一个位于这两个整数之间(含)的整数。
1 | from random import randint |
输出结果为:
1 | 4 |
另一个有用的函数是choic()。它将一个列表或元组作为参数,并随机返回其中的一个元素:
1 | from random import choice |
输出结果为:
1 | 5 |
9.6 类编码风格
类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例命名和模块命名都采用小写格式,并在单词之间加上下划线。
在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
需要同时导入标准库中的模块和编写的模块时,先编写导入标准库模块的语句,再添加一个空行,然后编写导入自己编写的模块语句。在包含多条import语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何处。