(一) 面向过程和面向对象编程

面向过程就是分析出解决问题所需要的步骤,然后一步一步地实现。

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

例如,五子棋,面向过程的设计思路就是首先分析问题的步骤:

1、开始游戏,
2、黑子先走,
3、绘制画面,
4、判定输赢,
5、轮到白子,
6、绘制画面,
7、判定输赢,
8、返回步骤2,
9、输出最后结果。

把上面每个步骤用分别的函数来实现,问题就解决了。

而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:

1、黑白双方,这两方的行为是一模一样的,
2、棋盘系统,负责绘制画面,
3、规则系统,负责判定诸如犯规、输赢等。

第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

(二) 类和对象

在面向对象编程的基础之上,衍生出了对象的概念。类是对客观世界中事物得抽象,而对象是类实例化后的实体。例如,汽车模型就是一个类,制造出来的每辆汽车就是一个对象。

<1> 在Python中创建类

  1. python使用class关键字定义一个类,类名的首字母一般要大写,例如:
1
2
class Person:
pass
  1. 类的主体由一系列的属性和方法组成,这里介绍类属性的操作。
  • 增加类属性的两种方式

增加类属性的第一种方式为:先定义好类之后,在后面的代码中来增加。形式是:类.属性 = 值

1
2
3
4
5
6
7
8
9
10
# 先定义一个类
class Person:
pass

# 增加类属性
Person.age = 18
Person.sex = "男"

# 验证属性增加结果
print(Person.__dict__)

增加类属性的第二种方式为:在定义类的过程中,定义属性。

1
2
3
4
5
6
7
# 定义类和类属性
class Person:
age = 18
sex = "男"

# 验证类属性增加结果
print(Person.__dict__)

在实践过程中,第二种方式更加的常用,第一种方式在某些特定的编程情景中可能更加的方便。

  • 通过del语句删除类属性
1
2
# 例如我们要删除上面定义的Person类的age属性
del Person.age
  • 通过赋值的方式修改类属性
1
2
3
4
5
6
7
8
9
class Person:
age = 18
sex = "男"

# 如我们要修改age属性为66
Person.age = 66

# 查看修改的结果
print(Person.age)

<2> 实例化对象

1
2
3
4
5
6
7
8
9
10
11
12
13
# 先创建一个类
class Person:
age = 18
sex = "男"

# 实例化对象
P = Person()

# 增加对象属性
P.height = 180

# 查看修改的结果
print(P.__dict__)

<3> 类和对象的内存存储

当创建一个类之后,会在计算机内存中开辟一个空间,用于存储,同时也会开辟出空间用于存储各个属性值。而所谓类.属性则是记录的是指向属性值的指针信息。

当修改属性的值时,会在内存空间重新开辟一个空间,存储新的值。然后将指针指向该新的值。

FIg 1.png

<4> 类的方法

类的主体为方法和属性,而方法的定义有三种方式:1 实例方式、2 类方式、3 静态方式。

  • 通过实例方式定义类方法

从下面的代码可以看到,方法是定义在类中的。另外,通过实例方式定义的方法,第一个参数是self,这个参数指的是调用时候的实例,如下述代码中,该参数指的就是实例P

1
2
3
4
5
6
7
8
# 首先定义类
class Person:
# 通过实例方式来进行定义。
def eat(self, food):
print("在吃", food)
# 调用类的方法
P = Person()
P.eat('土豆')
  • 通过类方式定义类方法

需要借助装饰器@classmethod进行定义,在定义方法前面,需要申明装饰器。此外,注意到方法中第一个参数为cls,即class的简写。它的含义为类,如下述代码中,cls的意义为Person类。

这种方式,也可以在实例层次上调用类。如果实在实例层次上调用,默认会将实例所对应的类,作为 cls 参数的输入。

1
2
3
4
5
6
7
8
9
10
11
12
# 定义类,通过类方式来定义类方法
class Person:
@classmethod
def eat(cls, food):
print("在吃", food)

# 在类层次上调用类方法
Person.eat('土豆')

# 在实例层次上调用类方法
P = Person()
P.eat('土豆')
  • 通过静态方式定义类方法

需要借助装饰器@staticmethod进行定义,在定义方法前面,需要申明装饰器。

1
2
3
4
class Person:
@staticmethod
def eat(food):
print("eating", food)

<5> 类方法的三种定义方式区别

通过实例方式定义的类方法,既可以调用类属性,也可以调用调用实例添加的实例属性,如Person.ageP.num都可以被这种方式调用。

类方式定义的方法,只可以调用类属性(Person.age),而不能调用实例属性(P.num)。

静态方法定义的方法,既不能调用类属性,也不能调用实例属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 首先定义一个类
class Person:
age = 18 #定义一个类属性

#通过实例方式定义方法
def shilifangfa(self):
print(self)
print(self.age)
print(self.num)

#通过类方式定义类方法
@classmethod
def leifangfa(cls):
print(cls)
print(cls.age)
print(cls.num)

#通过静态方式定义类方法
@staticmethod
def jingtaifangfa():
print(Person.age) #想要调用类属性,必须注明类名称

# 实例方法调用
P = Person()
P.num = 11
P.shilifangfa() #不会报错
P.leifangfa() #会报错,因为无法调用P.num
P.jingtaifangfa()

(三) 类属性和方法的注释文档

<1> 代码中的格式

规则1:在定义类后的第一行,使用三个双引号来添加类注释信息。注释信息应包含该类的作用、构造函数等描述。

规则2:类属性的注释放在“规则1”部分,并用如 Attributes 关键字来标记。

规则3:在定义类方法的第一行,使用三个双引号来添加类方法注释信息。在PyCharm中,编写完成方法后,再添加注释信息,会自动化补全参数注释格式,如下面代码中的:param distance:

规则4:定义完类之后,可以使用help()方法来查看注释信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person:
"""
第一,关于类的描述,类的作用,类的构造函数等等
第二,描述类的属性
Attributes:
name: string
"""
name = "Billy"
def run(self, distance):
"""
描述这个方法的作用等。
:param distance: 参数的含义、参数输入类型、是否有默认值等
:return:
"""
print(self.name, "is running.")
print("He has run for ", distance, "mile.")
return distance

help(Person) #可以打印出注释信息

help()查看的注释信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person(builtins.object)
| 第一,关于类的描述,类的作用,类的构造函数等等
| 第二,描述类的属性
| Attributes:
| name: string
|
| Methods defined here:
|
| run(self, distance)
| 描述这个方法的作用等。
| :param distance: 参数的含义、参数输入类型、是否有默认值等
| :return:
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| name = 'Billy'

<2> 生成注释文档

在编写复杂的程序时,就会定义非常多的类。此时,使用help()方法是不可行的。我们就可以借助Python的标准模块pydoc,以生成html格式的注释文件。

在上述代码文件目录下,打开终端,并输入下面的命令:

1
python -m pydoc -b

完成后,将在默认浏览器中开启一个网页,可以看到我们编写的类文件注释信息。

当然,也可以指定生成某个特定类文件的注释信息文件,如下。完成后将在该目录下产生一个html文件。

1
python -m pydoc -w leiwenjian.py

<3> 函数的注释

顺便提一下函数的注释规则,与类方法的注释规则很像,如下。

1
2
3
4
5
def food(name):
"""
函数的注释信息
"""
print("the food is ", name)