要看Python学得好与不好,基础占一半,剩下的另外一半分水岭则是面向对象,
而今天我所要介绍的内容就是Python中的面向对象。
类
在为了介绍清楚,面向对象究竟是个啥,我们必须要解锁一个前置知识点 —— 类;
Python中存在着各种各样的类,字符串str
是一个类,列表list
是一个类,字典是、元组是……
而且更为重要的一点,
对于刚接触编程语言的读者来说肯定会对于方法以及函数这两个概念产生疑惑,
调用函数的时候,我们使用函数名()
;当调用方法的时候,我们总是对象名.方法名()
,
举个例子,
当我们定义好了一个列表后,只需要在列表名字后面加上个点,后面就会出现append
、extend
等等的方法,
而当我们需要对列表直接进行求和却需要这样写sum(list)
,
而这篇文章则能够很好地解决以上的疑惑。
怎么定义类
定义类的过程与定义函数的过程一般无二,
需要使用到的是class
,
让我写一段示范代码,
class Test:
name = 'Joseph' # 这是属于类的静态属性
stand = 'Hermit·purple'
def __init__(self,age):
self.age = age #这是动态的属性
def get_stand(self): # 这是属于类的静态方法
return self.stand
以上就是定义一个类的过程,
在类的定义过程中,我们需要注意的是以下几点:
1)在定义类的过程中,需要对类的名字以大写字母开头,其作用就是与函数进行区分;
2)在定义类的过程中我们需要完成对类的属性以及方法完成定义,在类中完成定义的属性和方法都是静态的;
3)类定义的过程中明确的属性和方法即是静态的,而属于类实例的属性和方法则是动态的。
说到这里,大伙肯定都明悟了,
方法其实就是类中的函数,可既然两者的本质都是函数,那么为什么两者的使用方式却截然不同呢?
这一切都要归功于参数self
,这个参数代表的意义是自指,
我们接着上面的代码继续进行:
test = Test(56) # 得到一个类实例,同时传入参数age
test.get_stand() # 得到了替身隐者之紫
Test.get_stand(test) # 同样得到了隐者之紫
从以上关于get_stand
这个方法的两种使用方式的区别,就可以得出以下结论:
1)
self
参数代表的就是自指,当我们直接用类实例对象调用这个方法的时候其实就已经传入了self
,
就是这个类实例对象它自己;
2)而当我们从这个类对象Test
调用get_stand
这个方法的时候就需要传入参数self
;
类对象中的方法默认的第一个参数其实就是代表自指,self
这个名字是便于理解所默认的,
我们可以在类定义过程中将方法的第一个名字任意命名,
但此时Pycharm(如果使用的IDE是pychamr)会给出友情提示,Usually first parameter of a method is named 'self'
类对象、类实例
在上文介绍的过程中大伙其实就已经接触到了类对象和类实例这两个概念,
但在整个类的产生过程其实可以分为以下三个节点:类定义、类对象、类实例对象;
在我们定义、书写类的过程中,我们称之为类定义;
当完成类的定义后,这个类就足以被称为类对象了,正如上文中我们可以通过Test.get_stand(test)
来得到想要的结果一般,
在类定义结束后,其本身的属性、方法都是可以使用,也正因为如此它才足以被称为对象;
类实例对象就是上文中test = Test(56)
所实例化出来的,类实例对象继承了类对象中的所有静态属性和方法,同时自己也有一个动态属性age = 56
。
理清楚了类定义、类对象、类实例之后其实就已经对类这个概念有了最初步的认知,
就可以介绍什么才是面向对象。
面向对象
按照上文所说的,
Python中存在着多种多样的类对象、类实例,那岂不是我们一直都在面向对象?
对,也不对,
面向对象其实更多的是一种编程思维,编程范式,一种套路模板。
什么是面向对象
面向对象源自于生活中的抽象思维,提取不同事物的相同之处,将其整合为一个同一个类别,
然后再根据这个类不断去实例化出拥有自己动态属性得类实例,
我们只需要知道最本质的思维其实就已经了解什么是面向对象了。
Python中的列表其实就是面向对象最完美的体现,
每一个实例化出来的列表中所包含的元素都可能是不一样的(动态),
但是它们每一个类实例都可以使用类对象的方法(静态)。
当然我也可以跟其他博主一样,
说面向对象其实就是使用洗衣机一样,我们只需要将衣服扔进去、倒点洗衣液,这个洗衣机就会帮你完成
洗衣服的操作,后续的你都不用管,
虽然这是一种比较好的比喻方式,但是我总感觉有那么不贴切,对于不动编程的人来说这的确是一个很好
的比喻,但是对于需要去编写类的开发人员来说却不那么合适了,
因为对于开发人员来说,自己必须要清楚自己定义的类要具备哪些属性和方法。
面向对象与面向过程的区别
为了更深刻的理解什么是面向对象,什么是面向过程,
我们通过一个实际的小演练来讲解,
假设你有得到了一个商品列表,现在要求你以价格的从高到低进行排序,
你该怎么实现?
commodity_list = [
{
'商品编号': '00001', '商品名字': 'macbook_air', '商品价格': 7999},
{
'商品编号': '00001', '商品名字': 'macbook_pro', '商品价格': 13000},
{
'商品编号': '00001', '商品名字': 'iphone13', '商品价格': 6800},
{
'商品编号': '00001', '商品名字': 'redmi', '商品价格': 4333}
]
我们先把思路个理清楚
1)使用for循环遍历每一个字典,并且取出其中的’商品价格’;
2)嵌套一个for循环遍历其他字典,并且取出其中的商品价格;
3)比较两个商品价格,价格更高的往前排序。
我们稍微整理一下,就可以知道出大致怎么实现这个功能的思路,
这其实就是面向过程,
拆解出每一个步骤实现过程,并将其通过函数封装起来提高复用性。
ok,继续以上代码的编写,
commodity_list = [
{
'商品编号': '00001', '商品名字': 'macbook_air', '商品价格': 7999},
{
'商品编号': '00001', '商品名字': 'macbook_pro', '商品价格': 13000},
{
'商品编号': '00001', '商品名字': 'iphone13', '商品价格': 6800},
{
'商品编号': '00001', '商品名字': 'redmi', '商品价格': 4333}
]
for i in range(len(commodity_list)-1):
for j in range(i, len(commodity_list)):
if commodity_list[i]['商品价格'] < commodity_list[j]['商品价格']:
commodity_list[i], commodity_list[j] = commodity_list[j], commodity_list[i]
这就是面向过程的,将每一个步骤拆解出来,逐一完成,
这种思路在对小功能来说异常好用,可是对于大功能来说往往寸步难行;
我们可以尝试这是用面向对象的方式来继续修改以上,
其实修改思路很简单,只需要定义一个函数商品编号、商品名字、商品价格的商品类就行了,
这一点读者可以自己去尝试一下,
因为成为编程高手的方法只有两个 —— 1)键盘敲烂 2)借鉴别人代码然后键盘敲烂。
接下来我将会继续讲解类中的各种魔法方法,
其中包含着__init__
、__getattr__
等等,
只有了解、掌握这些方法才是对Python的面向对象有一定基础。
文章评论