- 面向对象和函数式编程的思想差异
- 函数式的思想:函数内部需要的数据均通过参数的形式传递。
- 面向对象的思想:将一些数据封装到对象中,在执行方法时,再去对象中获取。
- 类和对象的关系
- 对象是类的实例化,是基于类实例化出来”一块内存“,默认里面没有数据;经过类的
__init__
方法,可以在内存中初始化一些数据。
- 对象是类的实例化,是基于类实例化出来”一块内存“,默认里面没有数据;经过类的
- self是什么
- self,本质上就是一个参数。这个参数是Python内部会提供,其实本质上就是调用当前方法的那个对象。也就是说self指的是对象,而不是类!
- 面向对象编程中常见的成员:
- 绑定方法
- 实例变量
- 面向对象的三大特性
- 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。
- 继承,将类中的公共的方法提取到基类中去实现。
- 执行对象.方法时,优先去当前对象所关联的类中找,没有的话才去她的父类中查找。
- Python支持多继承:先继承左边、再继承右边的。
- self到底是谁?去self对应的那个类中去获取成员,没有就按照继承关系向上查找 。
```python class Base: def f1(self): print(‘before’) self.f2() # self是obj对象(Foo类创建的对象) obj.f2 print(‘base.f1’) def f2(self): print(‘base.f2’)
class Foo(Base): def f2(self): print(‘foo.f2’)
obj = Foo() obj.f1() # 优先去Foo类中找f1,因为调用f1的那个对象是Foo类创建出来的。
before foo.f2 # 注意这里不是base.f1,而是foo.f2,因为self指的是foo,而foo有f2 base.f1 ```
- 多态,Python默认支持多态(这种方式称之为鸭子类型),在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型,例如:一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。最简单的基础下面的这段代码即可。
```python class Email(object): def send(self): print(“发邮件”)
class Message(object): def send(self): print(“发短信”)
def func(arg): v1 = arg.send() print(v1)
v1 = Email() func(v1)
v2 = Message() func(v2)
- **面向对象的应用场景**
1. 将数据封装到一个对象,便于以后使用。(用户登录) <br />总结:数据封装到对象,以后再去获取。并且有规范数据(约束)的功能。注意:用字典也可以实现做封装,只不过字典在操作值时还需要自己写key,面向对象只需要 `.` 即可获取对象中封装的数据。
```python
class UserInfo:
def __init__(self, name, pwd,age):
self.name = name
self.password = pwd
self.age = age
def run():
user_object_list = []
# 用户注册
while True:
user = input("用户名:")
if user.upper() == "Q":
break
pwd = input("密码")
# user_object对象中有:name/password
user_object = UserInfo(user, pwd,19)
# user_dict = {"name":user,"password":pwd}
user_object_list.append(user_object)
# user_object_list.append(user_dict)
# 展示用户信息
for obj in user_object_list:
print(obj.name, obj.password)
- 将数据分装到对象中,在方法中对原始数据进行加工处理。(分页功能)
还有这个示例:将数据封装到一个对象中,然后再方法中对已封装的数据进行操作。
```python user_list = [“用户-{}”.format(i) for i in range(1,3000)]
分页显示,每页显示10条
while True: page = int(input(“请输入页码:”))
start_index = (page - 1) * 10
end_index = page * 10
page_data_list = user_list[start_index:end_index]
for item in page_data_list:
print(item)
```python
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:
self.current_page = 1
return
self.current_page = current_page
def start(self):
return (self.current_page - 1) * self.per_page_num
def end(self):
return self.current_page * self.per_page_num
user_list = ["用户-{}".format(i) for i in range(1, 3000)]
# 分页显示,每页显示10条
while True:
page = input("请输入页码:")
# page,当前访问的页码
# 10,每页显示10条数据
# 内部执行Pagination类的init方法。
pg_object = Pagination(page, 20)
page_data_list = user_list[ pg_object.start() : pg_object.end() ]
for item in page_data_list:
print(item)
import os
import requests
class DouYin:
def __init__(self, folder_path):
self.folder_path = folder_path
if not os.path.exists(folder_path):
os.makedirs(folder_path)
def download(self, file_name, url):
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):
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)
根据类创建多个对象,在方法中对对象中的数据进行修改。(警察和恐怖分子)
```python class Police: “””警察”””def init(self, name, role): self.name = name self.role = role if role == “队员”:
self.hit_points = 200
else:
self.hit_points = 500
def show_status(self): “”” 查看警察状态 “”” message = “警察{}的生命值为:{}”.format(self.name, self.hit_points) print(message)
def bomb(self, terrorist_list): “”” 投炸弹,炸掉恐怖分子 “”” for terrorist in terrorist_list:
terrorist.blood -= 200
terrorist.show_status()
“”” p1 = Police(“武沛齐”,”队员”) p1.show_status() p1.bomb([“alex”,”李杰”])
p2 = Police(“日天”,”队长”) p2.show_status() p2.bomb([“alex”,”李杰”]) “””
class Terrorist: “”” 恐怖分子 “””
def __init__(self, name, blood=300):
self.name = name
self.blood = blood
def shoot(self, police_object):
""" 开枪射击某个警察 """
police_object.hit_points -= 5
police_object.show_status()
self.blood -= 2
def strafe(self, police_object_list):
""" 扫射某些警察 """
for police_object in police_object_list:
police_object.hit_points -= 8
police_object.show_status()
def show_status(self):
""" 查看恐怖分子状态 """
message = "恐怖分子{}的血量值为:{}".format(self.name, self.blood)
print(message)
“”” t1 = Terrorist(‘alex’) t2 = Terrorist(‘李杰’,200) “””
def run():
# 1.创建3个警察
p1 = Police("武沛齐", "队员")
p2 = Police("苑昊", "队员")
p3 = Police("于超", "队长")
# 2.创建2个匪徒
t1 = Terrorist("alex")
t2 = Terrorist("eric")
# alex匪徒射击于超警察
t1.shoot(p3)
# alex扫射
t1.strafe([p1, p2, p3])
# eric射击苑昊
t2.shoot(p2)
# 武沛齐炸了那群匪徒王八蛋
p1.bomb([t1, t2])
# 武沛齐又炸了一次alex
p1.bomb([t1])
if name == ‘main‘: run()
- 补充:在Python3中编写类时,**默认都会继承object**(即使不写也会自动继承)。这一点在Python2是不同的:继承object,就是新式类,不继承object,经典类。
```python
class Foo:
pass
class Foo(object):
pass
作业
1、简述面向对象三大特性?
- 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。
- 继承,将类中的公共的方法提取到基类中去实现。
- 多态,Python默认支持多态(这种方式称之为鸭子类型)
2、将以下函数改成类的方式并调用
def func(a1):
print(a1)
- 答:
class Foo():
def func(self, a1):
print(a1)
obj = Foo()
obj.func("武沛齐")
3、面向对象中的self指的是什么?
- 答:
self是一个参数,在通过 对象.方法 的方式去执行方法时,这个参数会被python自动传递(值为调用当前方法的对象)
4、以下代码体现面向对象的什么特性?
class Person(object):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
obj = Person('武沛齐', 18, '男')
- 答:
封装
5、以下代码体现面向对象的什么特点?
class Message(object):
def email(self):
"""
发送邮件
:return:
"""
pass
def msg(self):
"""
发送短信
:return:
"""
pass
def wechat(self):
"""
发送微信
:return:
"""
pass
- 答:
封装
6、看代码写结果
class Foo:
def func(self):
print('foo.func')
obj = Foo()
result = obj.func()
print(result)
- 答
foo.func
None
7、看代码写结果
class Base1:
def f1(self):
print('base1.f1')
def f2(self):
print('base1.f2')
def f3(self):
print('base1.f3')
self.f1()
class Base2:
def f1(self):
print('base2.f1')
class Foo(Base1, Base2):
def f0(self):
print('foo.f0')
self.f3()
obj = Foo()
obj.f0()
- 答
foo.f0
base1.f3
base1.f1
8、看代码写结果:
class Base:
def f1(self):
print('base.f1')
def f3(self):
self.f1()
print('base.f3')
class Foo(Base):
def f1(self):
print('foo.f1')
def f2(self):
print('foo.f2')
self.f3()
obj = Foo()
obj.f2()
- 答:
foo.f2base.f1foo.f1 (还是先从obj对象即foo类开始找f1)
base.f3
9、补充代码实现
user_list = []
while True:
user = input("请输入用户名:")
pwd = input("请输入密码:")
email = input("请输入邮箱:")
"""
# 需求
1. while循环提示用户输入: 用户名、密码、邮箱(正则满足邮箱格式)
2. 为每个用户创建一个个对象,并添加到user_list中。
3. 当列表中的添加 3个对象后,跳出循环并以此循环打印所有用户的姓名和邮箱
"""
- 答
```python import re
class UserInfo(object): def init(self, name, pwd, email): self.name = name self.pwd = pwd self.email = email
def run(): user_list = [] while True: user = input(“请输入用户名:”) pwd = input(“请输入密码:”) email = input(“请输入邮箱:”) match_object = re.match(“(\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*)”, email, re.ASCII) if not match_object: print(“邮箱格式输入错误,请重新输入!”) continue
user_object = UserInfo(user, pwd, email)
user_list.append(user_object)
if len(user_list) == 3:
break
for item in user_list:
print(item.name, item.email)
if name == ‘main‘: main()
<a name="reYs0"></a>
### 10、补充代码:实现用户注册和登录。
```python
class User:
def __init__(self, name, pwd):
self.name = name
self.pwd = pwd
class Account:
def __init__(self):
# 用户列表,数据格式:[user对象,user对象,user对象]
self.user_list = []
def login(self):
"""
用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
:return:
"""
pass
def register(self):
"""
用户注册,每注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
:return:
"""
pass
def run(self):
"""
主程序
:return:
"""
pass
if __name__ == '__main__':
obj = Account()
obj.run()
答:
class User:
def __init__(self, name, pwd):
self.name = name
self.pwd = pwd
class Account:
def __init__(self):
# 用户列表,数据格式:[user对象,user对象,user对象]
self.user_list = []
def login(self):
"""
用户登录,输入用户名和密码然后去self.user_list中校验用户合法性
:return:
"""
print("用户登录")
while True:
user = input("请输入用户名(Q/q):")
if user.upper() == 'Q':
break
pwd = input("请输入密码:")
for user_object in self.user_list:
if user == user_object.name and pwd == user_object.pwd:
print("登录成功")
break
else:
print("登录失败")
def register(self):
"""
用户注册,每注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
:return:
"""
print("用户注册")
while True:
user = input("请输入用户名(Q/q):")
if user.upper() == 'Q':
break
pwd = input("请输入密码:")
user_object = User(user, pwd)
self.user_list.append(user_object)
def run(self):
"""
主程序
:return:
"""
method_dict = {
"1": {"title": "登录", "method": self.login},
"2": {"title": "注册", "method": self.register},
}
message = ";".join(["{}.{}".format(k, v['title']) for k, v in method_dict.items()])
while True:
print(message)
choice = input("请选择功能(Q/q):")
if choice.upper() == 'Q':
break
info = method_dict.get(choice)
if not info:
print("选择错误,请重新选择")
continue
method = info['method']
method() # self.login() / self.register()
if __name__ == '__main__':
obj = Account()
obj.run()