大爽Python入门教程 7-1 认识类`class`
大爽Python入门公开课教案 点击查看教程总目录
1 介绍
面向过程与面向对象
学习python的小伙伴,应该会经常看到有教程说,python是面向对象的。
但是很多人写python代码,其实用的是面向过程的写法。
那么这里先来简单介绍下这两个概念。
- 面向对象编程(Object-oriented programming)
- 面向过程编程(Procedure-oriented programming)
这两个概念的中文意思还有点难理解。
我们先看下两个对应的英文的意思
- Object-oriented programming: 以对象为导向的编程方式
- Procedure-oriented programming: 以过程为导向的编程方式
到这里还是有点模糊不明白。
这里换一种符合中文思维方式的解释:
中文里面有个词,叫做事物。
这个词可以囊括一切,可以描述整个世界的所有。
而这个词,本身可以分成两个角度
- 事: 事件。
- 物: 物体。
我们可以从事的角度去认知世界,也可以从物的角度去认知世界。
对应到编程,
前者就是面向过程(用一件件事去组织代码),
后者就是面向对象(用一个个对象去组织代码)。
当然,到这里还是会有些抽象,这里建议先往后看,
看完本节所有内容之后,再回来理解下。
如果还抽象,那就再往后看,
看完本章所有内容之后,再回来理解下。
概念
在面向对象编程时,我们常常会用到以下概念。
- 类(Class)
- 对象(Object)
- 实例(Instance)
类(Class)
创建对象的蓝图/模板,描述了所创建的对象共同的特性和方法。
对象(Object)是某一个类(Class)的实例(Instance)
创建对象的实例的过程,被称为实例化(Instantiation)。
这里还是有点抽象,我们看一些别人对这些概念的解析。
以下均出自Stackoverflow
(https://stackoverflow.com/a/1486212)[https://stackoverflow.com/a/1486212]
A class is a blueprint which you use to create objects.
An object is an instance of a class - it's a concrete 'thing' that you made using a specific class.
So, 'object' and 'instance' are the same thing,
but the word 'instance' indicates the relationship of an object to its class.
类是用于创建对象的蓝图。
对象是类的实例 - 它是您使用特定类创建的具体“事物”。
所以,“object”和“instance”是同一个东西,
但是“instance”这个词表示一个对象与其类的关系。
(https://stackoverflow.com/a/3323377)[https://stackoverflow.com/a/3323377]
A blueprint for a house design is like a class description.
All the houses built from that blueprint are objects of that class.
A given house is an instance.
房屋设计的蓝图就像类描述。
根据该蓝图建造的所有房屋都是该类的对象。
给定的房子是一个实例。
总的来讲,
类相当于抽象的蓝本或者设计图。
对象是具体的实现。
比如一个别墅,它的设计图,可以类比成类,
按照这个设计图实际建成的则是对象。
根据一个设计图,可以实际建成很多个别墅,建造的过程就叫实例化。
一个类,可以创建很多个对象。
当然,到这里还是会有些抽象,这里建议先往后看,
看完本节所有内容之后,再回来理解下。
如果还抽象,那就再往后看,
看完本章所有内容之后,再回来理解下。
2 基本语法
定义一个类
基本格式如下
class ClassName:
... #类体
其中
class
是关键词,必须这么写,后面接一个空格ClassName
是类名,可以自由命名...
是类的内部语句,一般是写类方法(很像函数,具体见后面),也可以写一些其他的。
比如类内部不实现具体功能的时候,还可以写个pass
.
具体例子如下
class SimpleClass:
pass
这就是定义了一个基础的类SimpleClass
,其没有实现任何具体的功能。
创建对象
定义好了类之后,我们可以用这个类来创建对象。
创建语法很简单,基本格式如下
myobject = ClassName()
就是先写类名,再在类名后面加个括号,对象就创建好了
然后赋值给一个变量。
使用上面的例子中的类,创建对象的例子如下
simpleobject = SimpleClass()
simpleobject
就是SimpleClass
类的对象,也可以说是一个实例。
命名规范
类名可以自由定义,但是写法上,一般推荐使用驼峰命名法(Upper Camel Case)。
驼峰命名法,简单来讲,就是多个单词无间隔,每个单词首字母大写。
比如
student
: 驼峰命名得写法就是Student
course score
: 驼峰命名得写法就是CourseScore
补充一点:
对象的命名,一般使用小写就好。
小写时,多个单词可以用下划线_
分隔,也可以不分隔。
千万不能用空格分隔。
3 添加属性
但是上面的SimpleClass
类是没有任何属性和方法的。
我们大多数时候,要创建的类都是要有属性和方法的。
先介绍如何给类添加属性(attribute)。
类的属性一般在__init__
方法中创建(init
前后各有两个下划线__
)。
这里直接来个例子,长方形(Rectangle)有宽(width)高(height)属性
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
这里来详细介绍一下这个代码
__init__
: 其语法和函数一样,但是在类里的这些,一般都叫做方法。- 像
__init__
这样,名字前后各有两个下划线的方法,是有特殊功能的方法,每种都有特定的功能。 __init__
方法,是一个构造方法,用于创建对象。- 类的所有方法,首个参数都是
self
, 这个特殊的参数,
代表实例本身,可以理解为自身 __init__
方法,形参中必须有self
,之后的参数就可以自由定义了,但是定义了的,创建实例的时候要传递参数,就像函数定义和调用一样。
具体来讲,我们创建一个Rectangle
的实例的语法如下
rect = Rectangle(10, 20) # 内部调用`__init__`方法,
注意:这个时候的类名后面的括号中是有参数的。
这个语句在外面,调用的时候是这样子的。
在类的内部,会使用__init__
方法来做实际的工作,进行创建。
Rectangle(10, 20)
对应到类的内部,
相当于会执行这样的语句__init__(self, 10, 20)
,
其中self
不用我们管,可以认为是python类自动生成的。
此时rect
就是类的一个实例。
我们可以直接用.
语法,看这个实例的属性。
比如
print(rect.width) # 10
print(rect.height) # 20
rect.width = 5
print(rect.width) # 5
上面说过,self
代表实例本身。
在外面,这个实例叫rect
,函数内部叫做self
。
外面的rect.width
对应的就是self.width
。
外面可以获取实例的属性,也可以通过赋值来修改实例的属性。
4 添加方法
self
的一个作用,就是让其所拥有的属性,在类中能够跨方法访问(获取与修改)。
这里我们来一个例子,在类中添加一个自定义的方法。
比如Rect
类,这里添加一个计算出其面积的方法,
添加后类如下
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def get_area(self):
return self.width * self.height
使用示例如下
r1 = Rectangle(10, 20)
print(r1.get_area()) # 200
输出为200
这里再来说一下这个方法。
r1
就是实例,在类的内部为self
r1.get_area()
,在类的内部对应get_area(self)
。
get_area(self)
方法中的self.width
和self.height
都来源于构造方法__init__
中。
也就是width
和height
属性,在__init__
方法中定义,
在get_area(self)
方法中可以直接使用。
这也是写class
, 比较直观比较常用的优点:(在类中)能够跨方法使用属性。
补充练习:
给上面的长方形类添加一个方法,计算周长,
并调用下。
5 初步使用
接下来我们再来定义一些常见的形状,同时给这些形状都添加计算面积方法
等边三角形
class EqualTriangle:
def __init__(self, side):
self.side = side
def get_area(self):
return self.side * self.side * 3 ** (1/2) / 4
等边三角形的面积公式为\(\frac { \sqrt {3} } {4} a ^ 2\),其中a
是边长
程序中,可以用3 ** (1/2)
来计算\(\sqrt {3}\)
圆
class Circle:
def __init__(self, radius):
self.radius = radius
def get_area(self):
return 3.14 * self.radius * self.radius
圆的面积公式是\(\pi r^2\), 这里\(\pi\)取3.14
使用一
使用Rectangle
、EqualTriangle
、Circle
分别创建宽高为1的正方形,边长为1的等边三角形,半径为1的圆。
并输出各自的面积。
代码如下
r1 = Rectangle(1, 1)
t1 = EqualTriangle(1)
c1 = Circle(1)
print("Rectangle area: %s" % r1.get_area())
print("EqualTriangle area: %s" % t1.get_area())
print("Circle area: %s" % c1.get_area())
输出如下
Rectangle area: 1
EqualTriangle area: 0.4330127018922193
Circle area: 3.14
使用二
随便使用上面三个类创建多个对象,计算总面积。
比如,创建的对象如下
shapes = [
Rectangle(1, 2), EqualTriangle(3), Circle(4),
Rectangle(5, 6), EqualTriangle(7), Circle(8),
]
计算面积的代码如下
areas = 0
for shape in shapes:
areas += shape.get_area()
print(areas)
输出为
308.31473670974873