- 面向对象和函数式编程的思想差异
- 函数式的思想:函数内部需要的数据均通过参数的形式传递。
- 面向对象的思想:将一些数据封装到对象中,在执行方法时,再去对象中获取。
- 类和对象的关系
- 对象是类的实例化,是基于类实例化出来”一块内存“,默认里面没有数据;经过类的
__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,面向对象只需要 `.` 即可获取对象中封装的数据。```pythonclass UserInfo:def __init__(self, name, pwd,age):self.name = nameself.password = pwdself.age = agedef run():user_object_list = []# 用户注册while True:user = input("用户名:")if user.upper() == "Q":breakpwd = input("密码")# user_object对象中有:name/passworduser_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) * 10end_index = page * 10page_data_list = user_list[start_index:end_index]for item in page_data_list:print(item)
```pythonclass Pagination:def __init__(self, current_page, per_page_num=10):self.per_page_num = per_page_numif not current_page.isdecimal():self.current_page = 1returncurrent_page = int(current_page)if current_page < 1:self.current_page = 1returnself.current_page = current_pagedef start(self):return (self.current_page - 1) * self.per_page_numdef end(self):return self.current_page * self.per_page_numuser_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 osimport requestsclass DouYin:def __init__(self, folder_path):self.folder_path = folder_pathif 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 -= 200terrorist.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 = nameself.blood = blooddef shoot(self, police_object):""" 开枪射击某个警察 """police_object.hit_points -= 5police_object.show_status()self.blood -= 2def strafe(self, police_object_list):""" 扫射某些警察 """for police_object in police_object_list:police_object.hit_points -= 8police_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])# 武沛齐又炸了一次alexp1.bomb([t1])
if name == ‘main‘: run()
- 补充:在Python3中编写类时,**默认都会继承object**(即使不写也会自动继承)。这一点在Python2是不同的:继承object,就是新式类,不继承object,经典类。```pythonclass Foo:passclass 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 = nameself.age = ageself.gender = genderobj = Person('武沛齐', 18, '男')
- 答:
封装
5、以下代码体现面向对象的什么特点?
class Message(object):def email(self):"""发送邮件:return:"""passdef msg(self):"""发送短信:return:"""passdef 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:breakfor item in user_list:print(item.name, item.email)
if name == ‘main‘: main()
<a name="reYs0"></a>### 10、补充代码:实现用户注册和登录。```pythonclass User:def __init__(self, name, pwd):self.name = nameself.pwd = pwdclass Account:def __init__(self):# 用户列表,数据格式:[user对象,user对象,user对象]self.user_list = []def login(self):"""用户登录,输入用户名和密码然后去self.user_list中校验用户合法性:return:"""passdef register(self):"""用户注册,每注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。:return:"""passdef run(self):"""主程序:return:"""passif __name__ == '__main__':obj = Account()obj.run()
答:
class User:def __init__(self, name, pwd):self.name = nameself.pwd = pwdclass 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':breakpwd = input("请输入密码:")for user_object in self.user_list:if user == user_object.name and pwd == user_object.pwd:print("登录成功")breakelse:print("登录失败")def register(self):"""用户注册,每注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。:return:"""print("用户注册")while True:user = input("请输入用户名(Q/q):")if user.upper() == 'Q':breakpwd = 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':breakinfo = method_dict.get(choice)if not info:print("选择错误,请重新选择")continuemethod = info['method']method() # self.login() / self.register()if __name__ == '__main__':obj = Account()obj.run()
