初始Python篇(10)—— 初识 类与对象
找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏: Python
目录
前言介绍
类的定义和使用
动态绑定属性与方法
前言介绍
Python 是一门既支持面向过程,又支持面向对象的编程语言。如果有小伙伴学过C语言 和 Java的话,就会发现 Python 是类似于两者的结合体,C语言是支持纯面向过程的,而Java是支持纯面向过程的。
前面我们都是在学习面向过程,今天我们就要来学习面向对象了。两者的区别就在于对同一件事情的处理角度不同。例如,同样是去吃饭,面向对象的角度,就是关注:人、饭馆、菜 这些对象;而面向过程的角度,就会关注:怎么去?怎么点菜?怎么吃饭?这些过程是如何去实现的。下面我们就来看类的定义与使用。
类的定义和使用
在Python中一切皆是对象。例如,田园犬、宠物犬等都是属于对象,它们都有自己的名字、年龄、性别等,这些我们都统称为对象的属性。我们之前在学习函数的时候,了解了函数的作用之一:对需要重复调用的代码进行封装。而这里的对象的很多属性也都是会重复出现的,因此我们把这些重复出现的属性封装成类似函数一样的,就统称为"类",当然类中不只是属性,还有一种共有的行为也被封装为了方法。类就是用来描述对象的,是创建对象的模版。
语法:
class 类名():
... // 属性
... // 方法
代码演示:
# Dog 是类名,通常首字母大写,后面跟着"()"
class Dog():
# 类中存在 属性 与 行为(被封装成方法)
# 下面的 name 与 age 都是属性 —> 类属性
name=''
age=0
# 在 __init__方法中定义的是属于实例属性
def __init__(self):
self.sex = '♂'
先来解释几个名词的含义吧。
1、封装:隐藏内部的实现细节,对外提供接口,这是属于面向对象编程的三大特性之一。例如,我们生活中所使用的USB接口,我们想要通过 U盘 传输数据时,不必了解这个原理是如何实现的,只需要提供一个接口给我,插入U盘就行。
2、类属性:也被称为静态属性或者静态变量,这是一种属性,是类独有的,而不是对象的,每个对象都可以去访问它,但是访问的都是同一份。
3、实例属性:也被称为实例变量,这也是一种属性,是对象独有的,每个对象去访问实例属性时,是访问它自己的,每一个对象都有一份。
注意:当类属性与实例属性一致时,优先访问实例属性,因为这是在对象内部寻找的,而类属性是需要在类中去寻找的。
类的出现就是为了更好的描述对象,那么怎么去创建对象呢?
语法:
# [参数1, 参数2, ...] 可省略
对象名 = 类名([参数1, 参数2, ...])
代码演示:
# 对象可以创建任意多个
dog1 = Dog()
dog2 = Dog()
dog3 = Dog()
() 中的参数是根据我们定义的 __init__方法中的参数来传输的,如果__init__方法中,没有参数,就不需要传输,如果有参数有需要传输。
注意:
1、类中的函数,我们都是称作方法。
2、通过类去创建对象的过程,我们称为 类的实例化,将一个模版,变成了一个真实存在的对象。
上面学习了一个类的编写与类的实例化,我们来看完整的类,应该是由几部分组成。
我们也可以通过代码来演示一下:
class Dog():
# 类属性
sort='中华田园犬'
# 初始化对象的方法(构造方法)——>每个对象在创建时,都会调用它
# 如果这里的name与age不使用"self."的话,就是一个局部变量了,而不再是实例变量
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 静态方法
@staticmethod
def bark():
print('这是一个静态方法,里面不能出现与实例相关的属性或者方法')
# 类方法
@classmethod
def sort(cls):
print('这是一个类方法,里面也不能出现与实例相关的属性或者方法')
# 实例方法
def roll(self):
print(f'{self.name}正在地上打滚~')
# 实例化一个对象
# 实例属性与实例方法是通过对象去调用的
dog = Dog('大白', 5) # 需要传入参数构造对象(__init__)
dog.roll()
# 类属性、类方法、静态方法等都是通过类名去调用的
Dog.bark()
Dog.sort()
运行结果:
注意:
1、虽然类方法 与 静态方法都是需要通过类名来调用的,但不意味着两者的用途也是一致的。类方法通常用来操作与类相关的属性;而静态方法一般是起到函数的作用,用来执行什么样的功能。
2、类方法 与 静态方法虽然表面上说是只能通过 类名 来调用,但实际上也是可以方法名来调用的。如下所示:
动态绑定属性与方法
当我们实例出多个对象之后,可能某些对象需要一些特殊的属性,而这些属性是不能存在于模版(类)中的,因此,我们只能通过动态绑定来修改对象的属性或者方法。
在正式学习之前,我们先来看一个小故事:相比大家应该都看过《无间道》,这里面的刘建明(下面用 刘 来代替) 与 陈永仁(下面用 陈 来代替) 分别是 黑社会安插在警方 与 警方安插在黑社会的卧底。假设 警察 与 黑社会 就是两个类,而 陈 与 刘 就是两个类分别实例化出来的对象,但是后面双方高层都决定要对方的潜入敌方阵营,因此这里就需要更改身份(程序运行的过程中,而不是创建的过程中,原本的身份早已注定),这里就需要用到动态绑定。
代码演示:
class Police():
# 类属性
id = '人民警察'
# 实例方法
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def identity(cls):
print(f'我是{cls.id}')
class Underworld():
id = '黑社会'
# 实例方法
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def identity(cls):
print(f'我是{cls.id}')
def deepIdentify(deepId):
print(f'我是{deepId}')
chen = Police('陈永仁', 20, '男')
liu = Underworld('刘建明', 20, '男')
huang = Police('黄警官', 32, '男')
han = Underworld('韩琛', 34, '男')
print('故事背景:')
print('香港警方为了剿灭黑社会团体,于是安插了陈永仁在黑社会当卧底,'
'而韩琛为了存活,则派遣刘建明等人潜入警方卧底')
print('命运的齿轮开始转动,两者的身份开始转换:')
print('='*30)
chen.id = '黑社会'
chen.deepId = '人民警察' # 动态绑定-属性
chen.deepIdentify = deepIdentify # 动态绑定-方法
liu.id = '人民警察'
liu.deepId = '黑社会' # 动态绑定-属性
liu.deepIdentify = deepIdentify # 动态绑定-方法
print(f'陈永仁的表面身份{chen.id},但其真实身份是{chen.deepId}')
print(f'刘建明的表面身份{liu.id},但其真实身份是{liu.deepId}')
print('='*30)
print(f'当陈永仁遇到{han.name}时,他会微笑着说出: ',end='')
chen.identity()
print(f'当陈永仁遇到{huang.name}时,他会情不自禁地说出: ',end='')
chen.deepIdentify (chen.deepId)
print('并时刻提醒自己不要堕落,要牢记初心与使用')
print('='*30)
print(f'当刘建明遇到{huang.name}时,他会微笑着说出: ',end='')
liu.identity()
print(f'当刘建明遇到{han.name}时,他会咬牙切齿地说出: ',end='')
liu.deepIdentify (liu.deepId)
print(f'并时刻想着杀了{han.name},过着自己现在的逍遥快乐的小日子')
运行结果:
注意:
1、动态绑定修改的是对象的属性 与 方法,并不会影响未修改的对象,即不会对类产生效果。
2、动态绑定的语法:
# 动态绑定修改属性
对象名.属性 = 属性值
# 动态绑定修改实例方法
对象名.调用时想要用到方法名 = 实际的方法名
# 调用修改的方法
对象名.调用时想要用到方法名([参数列表])
如果《无间道1》最后的结局是 黄警官一方大获全胜,而韩琛等人均被绳之以法的话,后面就需要恢复 刘 与 陈的真实身份,原来的假身份应当被彻底消除,相当于是删除动态绑定的方法与属性。
语法:
del 对象名.属性
del 对象名.方法
代码演示:
print('修改版剧情(纯写作需要,不喜勿喷):')
print('最终,刘建明良心发现,主动自首,给警方提供了韩琛等人的违法犯罪行为的证据,'
'警方立即出动,将其逮捕归案,陈永仁也成功获得了高级荣誉称号!')
print('接下来,就是修改 刘建明 与 陈永仁的相关档案了: ')
chen.id = '人民警察'
del chen.deepId
del chen.deepIdentify
liu.id = '黑社会'
del liu.deepId
del liu.deepIdentify
print(f'陈永仁的档案:{chen.name,chen.age,chen.sex,chen.id}')
print(f'刘建明的档案:{liu.name,liu.age,liu.sex,liu.id}')
print(liu.deepId) # error
print(chen.deepId) # error
运行结果:
既然属性与方法可以删除,那么对象 与 类是否也可以删除呢?确实如此,对象与方法也是可以删除的。
语法也是类似的,这里就直接给出代码了:
好啦!本期 初始Python篇(10)—— 初识 类与对象 的学习之旅 就到此结束啦!我们下一期再一起学习吧!