什么是面向过程编程
面向过程编程是一种编程思想,核心是“过程”二字。面向过程编程是一种基础的编程思想,它考虑的是实际地做事步骤。一般的面向过程是从上往下一步一步的走,所以面向过程最重要的是模块化的思想方法。基于该思想编写程序就好比在编写一条流水线,是一种机械式的编程方式。
举例:现在我们有这么一个要求:把大象装进冰箱。那么使用面向过程编程脑子中应该时刻想着我先干什么再干什么后干什么,也就是:1. 先打开冰箱门;2. 把大象装进去;3. 关闭冰箱门。
优点:负责的问题流程化,进而简单化
缺点:可扩展性极差
什么是面向对象编程
面向过程编程也是一种编程思想,核心是对象二字。(要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。
优点:可扩展性强
缺点:编程复杂度大大提高。
什么是类
在上面我们介绍了面向对象编程以及对象的概念。那么什么是类呢?一看到类我们首先想到的是种类,类其实就是种类的意思,是一系列相似的对象的集合体,对象是具体的实例,而类是虚拟的,不是客观存在的。举个例子:人类是一个虚拟的概念,我们无法通过人类去具体到某个人或物体,而你就是对象,是一个具现化的一个个体。
在现实世界中:世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念,也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
在程序中:务必保证先定义类,后产生对象。这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
在编写python程序时如何运用类与对象
上面我们说过,在程序中,应该先定义类再生成对象。但是我们没有一个具体的概念来说应该定义怎样一个类,我们可以通过具体的对象来概括出一个类进而把类定义出来。也就是通过现实世界中的对象来总结现实中的类,再通过现实中的类去定义程序中的类。
例:我们想要写一个类似王者荣耀所有英雄的类,那我们应该先去想具体英雄(对象)都有哪些,再来总结这些英雄(对象)所共同拥有的属性(特征)与行为(技能),然后总结出一个类,将其用代码表现出来。
在python中如何定义类:
在python中,我们使用class关键字来定义一个类,类名使用驼峰体命名法,类名后面直接加冒号。例:(class StudentManage:)
class Student:
name = 'Catalog Spri'
def run(self):
print('running')
这样,我们就简单的定义了一个类出来,类中有一个变量(属性)和一个函数(技能)。
注意:在定义类的时候,会执行类体代码!!!
注意:在定义类的时候,会执行类体代码!!!
注意:在定义类的时候,会执行类体代码!!!(这里所说的定义类不是说你敲代码时定义一个类,而是说在文件执行的时候,识别语法阶段,python解释器看到class关键字就明白你是要定义一个类,此时会执行类体代码)
得到一个类以后,我们要将类进行实例化得出一个对象。通过类名加括号:Student()就可以将类进行一次实例化(类可以进行无数次实例化)。我们需要用一个变量名去接收这个对象,例:stu1 = Student()。这样,stu1就是我们从Student这个类中实例化出来的一个对象。我们可以继续对类进行实例化得到另一个对象:stu2 = Student()。
这里有一个问题就是:我们的stu1与stu2中的属性是一模一样的,然而在现实世界中,我们的对象应该有不同的属性。那么我们就要来改进这个类,或者改进对象了。
我们可以通过这种方法来给对象赋一个新属性:
stu1 = Student()
stu1.age = 18
stu2 = Student()
stu2.age = 20
通过上面这种方法我们给对象传递了不同的属性,但是这种传递属性的方式难免太繁琐,python已经帮我们想好了要怎么去更简单的给对象传递不同的属性。
类中有一个函数叫做__init__函数。我们来详细了解一下init函数的作用
在学包的时候我们就已经接触过init了,init在python中是起到初始化的作用。前面我们说过,遇到__开头__结尾的都是内置的方法,在触发一定条件的时候会自动执行。在类中,当我们调用一个类产生对象的时候,就会直接执行__init__函数。产生的对象会当做参数self传入__init__函数中。看明白了这点以后,我们来看下面这段代码。
# 方式一、为对象初始化自己独有的特征
class People:
country = 'China'
x = 1
def run(self):
print('----->', self)
# 实例化出三个空对象
obj1 = People()
obj2 = People()
obj3 = People()
# 为对象定制自己独有的特征
obj1.name = 'egon'
obj1.age = 18
obj1.sex = 'male'
obj2.name = 'lxx'
obj2.age = 38
obj2.sex = 'female'
obj3.name = 'alex'
obj3.age = 38
obj3.sex = 'female'
# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
# print(People.__dict__)
# 方式二、为对象初始化自己独有的特征
class People:
country = 'China'
x = 1
def run(self):
print('----->', self)
# 实例化出三个空对象
obj1 = People()
obj2 = People()
obj3 = People()
# 为对象定制自己独有的特征
def chu_shi_hua(obj, x, y, z): # obj=obj1,x='egon',y=18,z='male'
obj.name = x
obj.age = y
obj.sex = z
chu_shi_hua(obj1, 'egon', 18, 'male')
chu_shi_hua(obj2, 'lxx', 38, 'female')
chu_shi_hua(obj3, 'alex', 38, 'female')
# 方式三、为对象初始化自己独有的特征
class People:
country = 'China'
x = 1
def chu_shi_hua(obj, x, y, z): # obj=obj1,x='egon',y=18,z='male'
obj.name = x
obj.age = y
obj.sex = z
def run(self):
print('----->', self)
obj1 = People()
# print(People.chu_shi_hua)
People.chu_shi_hua(obj1, 'egon', 18, 'male')
obj2 = People()
People.chu_shi_hua(obj2, 'lxx', 38, 'female')
obj3 = People()
People.chu_shi_hua(obj3, 'alex', 38, 'female')
# 方式四、为对象初始化自己独有的特征
class People:
country = 'China'
x = 1
def __init__(obj, x, y, z): # obj=obj1,x='egon',y=18,z='male'
obj.name = x
obj.age = y
obj.sex = z
def run(self):
print('----->', self)
obj1 = People('egon', 18, 'male') # People.__init__(obj1,'egon',18,'male')
obj2 = People('lxx', 38, 'female') # People.__init__(obj2,'lxx',38,'female')
obj3 = People('alex', 38, 'female') # People.__init__(obj3,'alex',38,'female')
# __init__方法
# 强调:
# 1、该方法内可以有任意的python代码
# 2、一定不能有返回值
class People:
country = 'China'
x = 1
def __init__(obj, name, age, sex): # obj=obj1,x='egon',y=18,z='male'
# if type(name) is not str:
# raise TypeError('名字必须是字符串类型')
obj.name = name
obj.age = age
obj.sex = sex
def run(self):
print('----->', self)
# obj1=People('egon',18,'male')
obj1 = People(3537, 18, 'male')
# print(obj1.run)
# obj1.run() #People.run(obj1)
# print(People.run)
# !!!__init__方法之为对象定制自己独有的特征
由此,我们就实现了为对象定制不同属性的简单方法。我们也就应该用这种方法。
注意:__init__函数中可以有任意的python代码,但是不提倡出现逻辑代码;__init__函数一定不能有返回值
接下来,我们来讲一下调用一个类产生对象时都干了哪些事
1. 创建一个空对象
2. 执行__init__函数
3. 将产生的名称放入空对象的名称空间中
我们在定义类的时候就会执行类体代码,执行类体代码就会创建专属于类的名称空间。该名称空间与执行文件的名称空间是相互独立的。在我们调用类产生一个空对象的时候,又会产生对象的名称空间,对象的名称空间和类的名称空间存在某种联系,但是并不包含在类的名称空间中。我们在调用对象的名称时,会先查找对象的名称空间,如果对象的名称空间中没有该名称,会查找类的名称空间,但是永远不会去查找执行文件的名称空间!!!
类中有两种名称:一种是属性(变量名),另一种是技能(函数名)。
对于这两种名称的本质也是不同的。
当我们在对象中调用类的属性时就是查找的类名称空间中的属性,当我们在对象汇总调用类的技能时,实际上是将类中的函数与对象之间建立绑定关系。该种函数成为绑定方法。
绑定方法与函数之间存在一些不同:
绑定方法其实就是对象和函数得绑定在一起,在调用绑定方法时,会自动传入对象本身,最终执行的还是类中定义的函数,绑定方法仅仅是帮我们自动传入了对象。
区别:
普通函数在调用时,根据函数声明有几个参数就一定要传几个参数
而绑定函数在调用时,会自动传入对象本身,所以通常我们手写的参数个数比声明的少一个