Python开发-027_初识面向对象
Python中支持两种编程方式来写代码,分别是:函数式编程
、面向对象式编程
-
函数式
# 定义函数,在函数中实现功能 def func(): res = "一个NB的功能" return res # 执行函数 demo = func()
-
面向对象
# 定义类 class Foo(object): # 在类中定义方法 def func(self): print("一个NB的功能") # 实例化类的对象 obj = Foo() # 执行类中的方法 obj.func()
python支持两种编程方式(其他很多语言只支持一种),行业内对于函数式编程vs面向对象编程
之间谁更好的讨论也是难分胜负,我们不必非纠结于那种方式更好,编程语言支持工具,最重要的是把功能实现
1 快速使用面向对象
想要通过面向对象去实现某个或某功能需要以下两个步骤
class Message:
# 函数在对象中被称为方法 def 方法名(self,....) self是固定搭配
def send_email(self,email,content):
data = "给{}发邮件,内容是:{}".format(email,content)
print(data)
msg_object = Message() # 实例化一个对象 msg_object,创建了一个区域
msg_object.send_email("kinght@geekxk.com","注册成功")
- 定义类
- 通过class定义一个类
- py3之后默认类都继承object
- 类名称首字母大写&驼峰式命名(多单词每一个单词首字母大写)
- 在类中编写一个方法
- 在类种编写的函数称为方法
- 方法的第一个参数必须是self
- 通过class定义一个类
- 使用类
- 需要实例化一个对象
- 通过实例化的对象调用其中的方法
类中也可以同时定义多个方法
class Message:
def send_email(self, email, content):
data = "给{}发邮件,内容是:{}".format(email, content)
print(data)
def send_wechat(self, vid, content):
data = "给{}发微信,内容是:{}".format(vid, content)
print(data)
msg_object = Message()
msg_object.send_email("kinght@geekxk.com", "注册成功")
msg_object.send_wechat("kinght", "注册成功")
用面向对象编程写的类有点像归类的意思:将某些相似的函数划分到一个类中,但,这种编写方式让人感觉有些鸡肋
2 对象与self
类与包有一个类似的东西,就是__init__
,在类中也可以定义一个特殊的__init__ 初始化方法
,它在实例化类创建对象对象=类()
的时候会自动执行
话回路转,实例化类创建对象的时候,python会在内存中开辟一块空间存放数据,这块空间专属于独立的对象,在全局中调用这块空间中的变量对象名.变量名
,而如果要在方法中使用这块空间中的变量,这种方式就会被局限,所以在方法中这块儿空间的名称被指为self
,而调用变量则是self.变量名
class Message:
def __init__(self,content):
self.data = content
def send_mali(self,email):
data = "给{}发邮件,内容是{}".format(email,self.data)
print(data)
def send_wchat(self,vid):
data = "给{}发微信,内容是{}".format(vid,self.data)
print(data)
# 实例化Message创建对象msg_object
msg_object = Message("注册成功")
print(msg_object.data) # 注册成功
msg_object.send_mali("kinght@geekxk.com") # 给kinght@geekxk.com发邮件,内容是注册成功
msg_object.send_wchat("kinght") # 给kinght发微信,内容是注册成功
# 实例化Message创建对象msg_msg_object
msg_msg_object = Message("注册失败")
print(msg_msg_object.data) # 注册失败
msg_msg_object.send_mali("kinght@geekxk.com") # 给kinght@geekxk.com发邮件,内容是注册失败
msg_msg_object.send_wchat("kinght") # 给kinght发微信,内容是注册失败
通过上述的示例,你会发现:
- 对象,让我们可以在它的内部先封装一部分数据,以后想要使用时,再去里面获取。
- self,类中的方法需要由这个类的对象来触发并执行
对象.方法名
,且在执行时会自动将对象当做参数传递给self,以供方法中获取对象中已封装的值。
注意:除了self默认参数以外,方法中的参数的定义和执行与函数是相同。
当然,根据类也可以创建多个对象并执行其中的方法
面向对象的思想:将一些数据封装到对象中,在执行方法时,再去对象中获取。
函数式的思想:函数内部需要的数据均通过参数的形式传递。
- self,本质上就是一个参数。这个参数是Python内部会提供,其实本质上就是调用当前方法的那个对象。
- 对象,基于类实例化出来”一块内存“,默认里面没有数据;经过类的
__init__
方法,可以在内存中初始化一些数据。
3 常见成员
在编写面向对象相关代码时,最常见成员有:
- 实例变量,属于对象,只能通过对象调用
- 绑定方法,属于类,通过对象调用 或 通过类调用
注意:还有很多其他的成员,后续再来介绍
class Person:
def __init__(self, n1, n2):
# 实例变量
self.name = n1
self.age = n2
# 绑定方法
def show(self):
msg = "我叫{},今年{}岁。".format(self.name, self.age)
print(msg)
def all_message(self):
msg = "我是{}人,我叫{},今年{}岁。".format(Person.country, self.name, self.age)
print(msg)
def total_message(self):
msg = "我是{}人,我叫{},今年{}岁。".format(self.country, self.name, self.age)
print(msg)
p1 = Person("kinght",20) # 初始化,实例化了Person类的对象叫p1
p1.show() # 执行绑定方法
p2 = Person("QAQ",20)
Person.show(p2) # 执行绑定方法
4 应用示例
4.1 应用实例1:将注册信息封装成对象方便使用
class UserInfo:
def __init__(self,name,pwd):
self.name = name
self.pwd = pwd
def run():
user_object_list = []
while True:
username = input("请输入用户名(Q退出):").strip()
if username.upper() == "Q":
break
passwd = input("请输入密码:").strip()
# 将用户的注册信息封装实例化封装成对象
user_object = UserInfo(username,passwd)
# 将对象存储到列表中
user_object_list.append(user_object)
for obj in user_object_list:
# 循环调用各个实例化对象中封装的name和pwd值
print(obj.name,obj.pwd)
if __name__ == "__main__":
run()
注意:用字典也可以实现做封装,只不过字典在操作值时还需要自己写key,面向对象只需要 .
即可获取对象中封装的数据
总结:
- 数据封装到对象,以后再去获取。
- 规范数据(约束)
4.2 应用实例2:用户翻页系统,对输入进行预处理
将数据封装到对象中,在方法中对原始数据进行加工处理
class Pagination:
def __init__(self,current_page,per_page_num=10):
self.per_page_num = per_page_num
if not current_page.isdecimal():
# 输入非整数,默认返回第一页
self.current_page = 1
return
current_page = int(current_page)
if current_page < 1:
# 输入数字小于1,默认返回第一页
self.current_page = 1
return
self.current_page = current_page
# start函数和stop函数可以直接取封装的数据,不用再次传递
def start(self):
# 计算起始序号
return (self.current_page-1) * self.per_page_num
def stop(self):
# 计算结束序号
return self.current_page * self.per_page_num
def run():
User_list = ["用户-{}".format(i) for i in range(1, 3000)]
page = input("请输入页数:")
pg_object = Pagination(page,10)
page_data_list = User_list[pg_object.start():pg_object.stop()]
print(page_data_list)
if __name__ == "__main__":
run()
4.3 应用实例3:下载视频,在self中保存文件路径
import os,requests
class DouYin:
def __init__(self,folder_path):
'''
获得文件保存文件夹路径,如果路径不存在则生成文件夹
:param folder_path: 文件保存文件夹
'''
self.folder_path = folder_path
if not os.path.exists(folder_path): # 判断目录是否存在
os.makedirs(folder_path) # 创建目录
def download(self,file_name,url):
'''
下载视频
:param file_name: 视频文件名
:param url: 下载链接
:return: None
'''
res = requests.get(
url = url,
headers={
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
}
)
file_path = os.path.join(self.folder_path, file_name)
with open(file_path,mode='wb') as f:
f.write(res.content)
f.flush()
def multi_download(self,video_list):
'''
批量下载视频
:param video_list: 视频列表(文件名,下载链接)
:return:None
'''
for item in video_list:
self.download(item[0],item[1])
if __name__ == '__main__':
douyin_object = DouYin("videos")
douyin_object.download(
"罗斯.mp4",
"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg"
)
video_list = [
("a1.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg"),
("a2.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag"),
("a3.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
]
# 批量下载
douyin_object.multi_download(video_list)
4.4 实例应用4:匪徒游戏,将功能封装成模板
# 警匪游戏
class Police:
def __init__(self,name,role):
self.name = name
self.role = role # 职位
if role == "队员":
self.hit_points = 200 # 队员200血
else:
self.hit_points = 500 # 队长500血
def show_status(self):
# 查看警察状态
message = "警察姓名:{},当前血量:{}".format(self.name,self.hit_points)
print(message)
def bomb(self,terrorist_list):
# 警方攻击方式:投掷炸弹
for terrorits in terrorist_list:
terrorits.blood -= 20 # 调用了匪徒血量方法
terrorits.show_status()
class Terrorits():
def __init__(self,name):
self.name = name
self.blood = 300
def show_status(self):
message = "匪徒姓名:{},当前血量:{}".format(self.name,self.blood)
print(message)
def shoot(self,police_object):
police_object.hit_points -= 5
police_object.show_status() # 查看警察状态
# 后坐力
self.blood -= 1
self.show_status()
def strafe(self,police_object_list):
for police_object in police_object_list:
police_object.hit_points -= 3
police_object.show_status()
def run():
# 创建三个警察
p1 = Police("aaa",'队员')
p2 = Police("bbb",'队员')
p3 = Police("ccc",'队长')
# 创建2个匪徒
t1 = Terrorits('111')
t2 = Terrorits('222')
# 匪徒率先射击
t1.shoot(p1)
# 警察手雷还击
p3.bomb([t1,t2])
# 匪徒扫射
t2.strafe([p1,p2,p3])
if __name__ == '__main__':
run()
总结:
- 仅做数据封装。
- 封装数据 + 方法再对数据进行加工处理。
- 创建同一类的数据且同类数据可以具有相同的功能(方法)
Python开发-027_初识面向对象
http://localhost:8080/archives/Duo3Jppo